Apollo Server忽略自定义CORS配置并采用自身配置引发跨域错误求助
我之前也踩过这个一模一样的坑,Apollo Server的applyMiddleware方法里的cors配置优先级特别高——它会直接绕过你在Express中全局注册的CORS中间件,自己单独处理跨域请求。你现在的问题看起来是origin: true的配置在Apollo Server的CORS处理逻辑里没按预期生效,导致 fallback 到了通配符*,刚好和credentials: true冲突触发了错误。
这里给你几个可行的解决办法,按优先级排序:
1. 改用函数式的Origin配置(最稳妥)
把origin: true换成自定义函数,手动返回请求的Origin,能确保Apollo Server不会 fallback 到通配符。修改你的corsOptions如下:
var corsOptions = { origin: (origin, callback) => { // 直接返回请求的Origin,null场景可按需处理(比如本地开发允许指定域名) callback(null, origin || "http://localhost:3000"); }, optionsSuccessStatus: 200, credentials: true, };
然后保持applyMiddleware里的配置不变:
apolloServer.applyMiddleware({app, path: '/api/graphql', cors: corsOptions});
这个方法完全可控,你还能根据需要加额外校验逻辑(比如只允许指定域名的请求),同时避免origin: true可能带来的解析问题。
2. 禁用Apollo Server的CORS处理,完全依赖Express全局中间件
如果你更想让Express的全局CORS中间件处理所有请求,可以在applyMiddleware里把cors设为false,这样Apollo Server就会跳过自身的CORS处理,交给之前注册的app.use(cors(corsOptions))来处理:
apolloServer.applyMiddleware({app, path: '/api/graphql', cors: false});
注意:一定要确保全局CORS中间件注册在apolloServer.applyMiddleware调用之前,否则请求会先到达Apollo Server路由,导致中间件不生效。
3. 验证请求的Origin头是否正确携带
有时候问题出在请求本身——如果跨域请求没正确携带Origin头,CORS库会默认返回*。你可以在浏览器开发者工具里查看请求头,确认是否存在Origin字段,且值是你的前端域名(比如http://localhost:3000)。
如果是本地开发用file://协议打开页面,请求的Origin会是null,这种情况下即使设置origin: true也会返回*,这时候需要在origin函数里手动处理null的情况。
最后验证
修改配置后,发送一个带credentials: include的跨域请求,查看响应头:
- 应存在
Access-Control-Allow-Origin,值和请求的Origin完全一致 - 应存在
Access-Control-Allow-Credentials: true
这样就能解决你遇到的“当credentials模式为'include'时,Origin不能为*”的错误了。
内容的提问来源于stack exchange,提问作者Pero122

