CORS 请求中 Access-Control-Allow-Headers 到底该怎么配?
我在前端用 fetch 发了个带自定义 header 的请求,比如 X-Custom-Token,但浏览器报错说这个 header 被 CORS 策略拦了。后端是用 Express 写的,我已经加了 Access-Control-Allow-Origin: *,但好像还不够?
查了文档说要加 Access-Control-Allow-Headers,但我试了下面这样还是不行:
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'X-Custom-Token');
next();
});
是不是漏了什么?为什么浏览器还是报错说不允许这个 header?
Access-Control-Allow-Headers: X-Custom-Token,但浏览器在发预检请求(OPTIONS)的时候,会把所有你实际请求里要带的自定义 header 都列出来,而你后端只允许了其中一个,其他没允许的就会被拦。更关键的是,如果你用的是 fetch 并且设置了
headers字段,哪怕只是加了一个自定义 header,浏览器都会先发一个 OPTIONS 预检请求,这时候后端必须正确响应这个 OPTIONS 请求,而且要返回所有你需要的 header。你现在的中间件只处理了普通请求(比如 GET/POST),但没处理 OPTIONS 预检请求,所以浏览器压根没收到允许的 header 列表。
可以这样改:
注意几点:
1.
Access-Control-Allow-Headers里要把你实际会用到的所有自定义 header 都列出来,比如X-Custom-Token、Content-Type(如果你发 JSON 就需要)、Authorization(如果带 token)等等,一个都不能少。2. 一定要处理
OPTIONS请求,不然它卡在预检阶段就直接报错了,后端甚至不会走到你真正的路由逻辑。3. 如果你用的是
cors中间件,其实更省事,直接:我之前踩坑的时候就是漏了
Content-Type,以为只配自定义 header 就行,结果一发 JSON 就挂,后来发现浏览器默认会加Content-Type: application/json,没允许它也会报 CORS 错。你试试把
OPTIONS处理加上,再把需要的 header 全塞进Access-Control-Allow-Headers,应该就能通了。