使用apollo-server-express时远程环境图片上传的CORS问题求助
问题:远程环境下Apollo Server文件上传POST请求CORS 403错误
服务配置
Express配置
// Express setup const app = express() app.use(graphqlUploadExpress({ maxFileSize: 10000000, maxFiles: 10 })) app.use(cors())
Apollo配置
// Apollo setup const server = new ApolloServer({ schema, context, plugins: [ ApolloServerPluginDrainHttpServer({ httpServer: http.createServer(app), stopGracePeriodMillis: 10000, }), ], introspection: process.env.NODE_ENV !== 'production', }) await server.start() // Mount Apollo middleware server.applyMiddleware({ app, cors: false, path: '/' })
依赖版本
"apollo-server-core": "^3.10.2", "apollo-server-express": "^3.4.0", "cors": "^2.8.5", "express": "^4.17.1", "graphql": "^16.0.1", "graphql-upload": "^15.0.0",
问题描述
- 仅远程环境下图片上传触发CORS相关错误,OPTIONS请求返回头正常(含
Access-Control-Allow-Origin: *),但POST请求返回403 - 同一POST请求在Postman/Apollo Studio可成功执行,本地环境无问题
- 已尝试调大
maxFileSize,无效
解决办法
统一CORS配置,避免规则冲突
当前Apollo挂载时设置cors: false,但Express层面启用了cors(),远程环境反向代理可能导致规则叠加冲突。建议在Apollo中显式指定CORS规则,和Express保持一致,同时可移除Express层面的app.use(cors()):server.applyMiddleware({ app, cors: { origin: '*', credentials: true, allowedHeaders: ['Content-Type', 'Authorization'] }, path: '/' })排查远程环境反向代理配置
多数远程环境403是代理层问题而非服务本身:- 确保Nginx等代理允许
multipart/form-data类型的请求 - 检查是否有安全拦截规则(如ModSecurity)阻断了带文件的POST请求
- 确认代理配置完整传递
Origin及Access-Control-*相关请求头
- 确保Nginx等代理允许
调整graphql-upload的适配参数
远程环境的网络或服务器限制可能导致请求处理异常,可补充调整上传配置:app.use(graphqlUploadExpress({ maxFileSize: 10000000, maxFiles: 10, maxFieldSize: 10000000, // 增大字段大小限制 createReadStream: (file) => { return file.createReadStream({ highWaterMark: 64 * 1024 }) // 调整流缓冲区大小 } }))修正Apollo Server的httpServer实例配置
当前插件中直接创建新的httpServer可能和Express实例冲突,建议提前创建统一实例:const httpServer = http.createServer(app); const server = new ApolloServer({ schema, context, plugins: [ ApolloServerPluginDrainHttpServer({ httpServer, stopGracePeriodMillis: 10000, }), ], introspection: process.env.NODE_ENV !== 'production', }) await server.start() server.applyMiddleware({ app, cors: ..., path: '/' }) await new Promise(resolve => httpServer.listen({ port: 4000 }, resolve))验证生产环境变量配置
确认远程环境NODE_ENV是否正确设置为production,检查端口、域名等环境变量是否导致请求路径或跨域规则不匹配
内容的提问来源于stack exchange,提问作者mikipero
相关产品推荐
相关产品推荐

