![](/img/trans.png)
[英]cors error: No 'Access-Control-Allow-Origin' header apollo-server-express
[英]apollo-server-express CORS issue
所以我正在迁移到 apollo-server-express 2.3.3 (我使用的是 1.3.6 )我遵循了几个指南,进行了必要的调整,但陷入了 CORS 问题。
根据文档,您必须使用 applyMiddleware function 将 apollo 服务器与 express 连接起来。
我目前正在执行以下操作:
const app = express();
// CORS configuration
const corsOptions = {
origin: 'http://localhost:3000',
credentials: true
}
app.use(cors(corsOptions))
// Setup JWT authentication middleware
app.use(async (req, res, next) => {
const token = req.headers['authorization'];
if(token !== "null"){
try {
const currentUser = await jwt.verify(token, process.env.SECRET)
req.currentUser = currentUser
} catch(e) {
console.error(e);
}
}
next();
});
const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ req }) => ({ Property, User, currentUser: req.currentUser })
});
server.applyMiddleware({ app });
const PORT = process.env.PORT || 4000;
app.listen(PORT, () => {
console.log(`Server listening on ${PORT}`);
})
由于某种原因,我的快速中间件似乎没有执行,当我尝试从 localhost:3000 (客户端应用程序)发出请求时,我得到典型的 CORS 错误
使用 apollo-server-express 1.3.6,我可以毫无问题地执行以下操作:
app.use(
'/graphql',
graphqlUploadExpress({ maxFileSize: 10000000, maxFiles: 10 }),
bodyParser.json(),
graphqlExpress(({ currentUser }) => ({
schema,
context: {
// Pass Mongoose models
Property,
User,
currentUser
}
}))
);
现在有了新版本,尽管文档使这看起来像一个简单的迁移,但我似乎无法使其工作。 我检查了各种文章,似乎没有人遇到问题。
根据我对 Apollo Server 中间件 API 的理解,CORS 选项、body-parser 选项和 graphql 端点被视为必须直接传递给applyMiddleware
参数对象的特殊实体。
所以你想尝试以下配置:
const app = express();
// CORS configuration
const corsOptions = {
origin: 'http://localhost:3000',
credentials: true
}
// The following is not needed, CORS middleware will be applied
// using the Apollo Server's middleware API (see further below)
// app.use(cors(corsOptions))
// Setup JWT authentication middleware
app.use(async (req, res, next) => {
const token = req.headers['authorization'];
if(token !== "null"){
try {
const currentUser = await jwt.verify(token, process.env.SECRET)
req.currentUser = currentUser
} catch(e) {
console.error(e);
}
}
next();
});
const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ req }) => ({ Property, User, currentUser: req.currentUser })
});
// There is no need to explicitly define the 'path' option in
// the configuration object as '/graphql' is the default endpoint
// If you planned on using a different endpoint location,
// this is where you would define it.
server.applyMiddleware({ app, cors: corsOptions });
const PORT = process.env.PORT || 4000;
app.listen(PORT, () => {
console.log(`Server listening on ${PORT}`);
})
与阿波罗服务器2.X您提供cors
在构造领域ApolloServer
。
所以在你的情况下,它应该如下所示:
const corsOptions = {
origin: 'http://localhost:3000',
credentials: true
}
// Setup JWT authentication middleware
app.use(async (req, res, next) => {
const token = req.headers['authorization'];
if(token !== "null"){
try {
const currentUser = await jwt.verify(token, process.env.SECRET)
req.currentUser = currentUser
} catch(e) {
console.error(e);
}
}
next();
});
const server = new ApolloServer({
typeDefs,
cors: cors(corsOptions),
resolvers,
context: ({ req }) => ({ Property, User, currentUser: req.currentUser })
});
server.applyMiddleware({ app });
const PORT = process.env.PORT || 4000;
app.listen(PORT, () => {
console.log(`Server listening on ${PORT}`);
})
在这里您可以找到 apollo 服务器接受的所有参数: https : //www.apollographql.com/docs/apollo-server/api/apollo-server.html#Parameters-2
在这里你可以找到相关的讨论: https : //github.com/apollographql/apollo-server/issues/1142
CORS 设置来自 ExpressJS,而不是来自 ApolloServer。 如果要添加自定义或通配符来源,则必须使用回调/处理程序函数来处理它。
const server = new ApolloServer({
....,
cors: {
credentials: true,
origin: (origin, callback) => {
const whitelist = [
"http://site1.com",
"https://site2.com"
];
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error("Not allowed by CORS"))
}
}
}
});
默认情况下,express 中间件将使用 graphql 路径上的默认选项实例化 cors 中间件,覆盖您自己为其他路径指定的任何 cors 中间件配置(!)
您可以在应用 apollo 中间件时覆盖默认值,例如
apollo.applyMiddleware({ app, cors: {credentials: true, origin: true} })
我正在使用 apollo-server-express 2.17
只需删除 csrfPrevention: true 并且您对 go 很好
import { ApolloServer } from 'apollo-server-express'; import { ApolloServerPluginDrainHttpServer } from 'apollo-server-core'; import express from 'express'; import http from 'http'; async function startApolloServer(typeDefs, resolvers) { // Required logic for integrating with Express const app = express(); // Our httpServer handles incoming requests to our Express app. // Below, we tell Apollo Server to "drain" this httpServer, // enabling our servers to shut down gracefully. const httpServer = http.createServer(app); // Same ApolloServer initialization as before, plus the drain plugin // for our httpServer. const server = new ApolloServer({ typeDefs, resolvers, csrfPrevention: true, cache: 'bounded', plugins: [ApolloServerPluginDrainHttpServer({ httpServer })], }); // More required logic for integrating with Express await server.start(); server.applyMiddleware({ app, // By default, apollo-server hosts its GraphQL endpoint at the // server root. However, *other* Apollo Server packages host it at // /graphql. Optionally provide this to match apollo-server. path: '/', }); // Modified server startup await new Promise(resolve => httpServer.listen({ port: 4000 }, resolve)); console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`); }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.