fetch携带credentials加自定义请求头触发CORS错误,服务端已配置头如何解决?
问题原因
- 未添加自定义请求头时,你的GET请求属于CORS简单请求范畴,浏览器不会发送OPTIONS预检请求,直接携带你配置的CORS头返回响应,因此请求正常。
- 新增
X-Username、X-Password自定义请求头后,请求变为非简单请求,浏览器会自动先发送OPTIONS预检请求验证跨域权限。你当前的CORS头仅配置在业务接口上,没有对OPTIONS请求做处理,Spark Java默认返回的OPTIONS响应头中Access-Control-Allow-Origin为通配符*,和credentials: include规则冲突,因此触发报错。
解决方法
你需要在Spark Java中全局配置CORS规则,覆盖所有请求包括OPTIONS预检请求,示例配置如下:
// 全局前置过滤器,给所有请求添加CORS响应头 before((req, res) -> { // 建议动态获取请求头中的Origin,判断是否为允许的域名后再返回,适配多域名场景 String allowOrigin = req.headers("Origin"); // 如果你只允许固定域名,直接替换为你的domain变量即可 res.header("Access-Control-Allow-Origin", allowOrigin); res.header("Access-Control-Allow-Credentials", "true"); res.header("Access-Control-Allow-Headers", "X-Username, X-Password, Content-Type"); res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); // 缓存预检结果1小时,减少重复OPTIONS请求开销 res.header("Access-Control-Max-Age", "3600"); }); // 单独处理所有OPTIONS预检请求,直接返回200状态码 options("/*", (req, res) -> { res.status(200); return ""; });
注意事项
- 确保
Access-Control-Allow-Origin返回值和前端请求的Origin完全一致,包含协议、域名、端口三个部分,任何一处不匹配都会触发跨域错误 - 不要在反向代理层(如Nginx)重复配置CORS响应头,重复配置会导致浏览器识别失败
- 如果需要允许多个域名跨域,可在过滤器中增加Origin白名单校验逻辑,仅当请求Origin在白名单内时返回对应的Origin值即可
内容的提问来源于stack exchange,提问作者SonMooSans
相关产品推荐
相关产品推荐

