为什么CORS预检请求返回403时,我的自定义头被服务器拒绝了?

诸葛利伟 阅读 713

最近在做跨域文件上传时遇到个问题:前端用fetch发送POST请求带了multipart/form-data格式和自定义头X-File-Hash,但预检OPTIONS请求一直返回403。服务器日志显示:”Request header field X-File-Hash is not allowed by CORS policy”。

我检查过服务器配置,确实设置了

// Node.js Express配置示例
app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "https://myfrontend.com");
  res.header("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
  res.header("Access-Control-Allow-Headers", "X-File-Hash, Content-Type");
  next();
});

但奇怪的是,当我把X-File-Hash头从请求中移除后,请求就能成功。难道服务器配置需要显式允许所有安全敏感头?或者预检请求需要额外的验证步骤?

另外,我在前端CSS里尝试过设置


.upload-form {
  /* 这个样式和问题无关,但想确认是否影响请求头 */
  content: attr(data-x-file-hash);
}

结果发现样式不影响问题,核心问题还是在CORS头配置上。

我来解答 赞 4 收藏
二维码
手机扫码查看
1 条解答
南宫秋梓
你这个配置看起来只差一步了。问题出在服务器允许的 headers 没有正确覆盖所有自定义头字段。你已经在 Access-Control-Allow-Headers 里加了 X-File-Hash,但如果你用了认证或者 cookies,还要显式加上 Authorization 或者 X-Requested-With 这类默认安全头,否则浏览器也会拒绝。

另外,你的中间件写法有个坑:res.header 在 Express 里推荐用 response.header(key, value) 多次调用,而不是链式写法,否则可能某些 header 没传进去。建议改成这样:

app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "https://myfrontend.com");
res.header("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
res.header("Access-Control-Allow-Headers", "X-File-Hash, Content-Type, Authorization");
next();
});

还有一个点是,有些服务器框架(比如 Express 的某些 CORS 插件)在处理 OPTIONS 请求时需要特别处理,建议加个专门的 OPTIONS 路由兜底:

app.options('/your-upload-path', (req, res) => {
res.sendStatus(200);
});

最后,如果你前端设置了 credentials: 'include',那服务器还必须设置 Access-Control-Allow-Credentials,否则也可能触发 403。这个配置也要加进去:

res.header("Access-Control-Allow-Credentials", "true");

这些都加上以后再试试,应该能解决头被拒绝的问题。
点赞 4
2026-02-05 20:11