Express req.headers参数丢失:跨域请求时access_token无法获取
解决Express跨域场景下无法获取自定义请求头的问题
这个问题我之前排查过类似的,大概率是跨域请求的自定义请求头被浏览器拦截或者中间代理层过滤掉了,咱们一步步拆解原因和解决方案:
核心原因1:跨域预检请求(OPTIONS)未正确处理
当你发送带自定义头(比如access_token)的跨域请求时,浏览器会先发起一次OPTIONS预检请求,确认服务器是否允许这个自定义头。如果服务器没有正确响应预检请求,浏览器会直接阻止后续的实际请求,自然后端就拿不到access_token头。而localhost是同源请求,不需要预检,所以能正常获取。
解决方案:配置CORS允许自定义头
推荐用Express官方常用的cors中间件来处理,明确指定允许的自定义头:
const express = require('express'); const cors = require('cors'); const app = express(); // 生产环境建议指定具体的Azure域名,不要用* const corsConfig = { origin: 'https://your-azure-domain.com', allowedHeaders: ['access_token', 'Content-Type'], // 把你的自定义头加在这里 methods: ['GET', 'POST', 'OPTIONS'] // 确保OPTIONS方法被允许 }; app.use(cors(corsConfig)); // 或者如果不想用第三方包,手动处理OPTIONS请求 app.options('*', (req, res) => { res.setHeader('Access-Control-Allow-Origin', 'https://your-azure-domain.com'); res.setHeader('Access-Control-Allow-Headers', 'access_token, Content-Type'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.sendStatus(200); });
核心原因2:中间代理/CDN过滤了自定义请求头
你的API部署在AWS,请求从Azure域名过来,可能经过了AWS API Gateway、CloudFront,或者Azure侧的代理服务,很多代理默认会过滤非标准的自定义请求头(有些服务对不带X-前缀的头会做限制,虽然HTTP标准没强制要求),导致头无法传递到Express后端。
解决方案:检查代理配置透传自定义头
- 如果用AWS API Gateway:在集成请求的"HTTP Headers"里添加
access_token,设置映射为method.request.header.access_token,确保头能从请求端传递到后端。 - 如果用Nginx等反向代理:在配置里添加
proxy_set_header access_token $http_access_token;,保证自定义头被透传。 - 测试直接访问AWS的API域名(绕过Azure域名),看能不能获取
access_token,如果可以,那问题肯定出在Azure侧的代理配置。
额外排查步骤
- 打开浏览器开发者工具的Network面板,查看实际发送的请求里是否包含
access_token头:- 如果Request Headers里没有这个头,说明是浏览器预检失败,回到第一个原因处理。
- 如果有这个头但后端拿不到,说明是中间代理过滤了,检查代理配置。
- 确保你的自定义头名没有特殊字符(比如下划线是允许的,但有些老代理可能有问题,实在不行可以改成
X-Access-Token试试)。
内容的提问来源于stack exchange,提问作者Andrey Radkevich
相关产品推荐
相关产品推荐

