Nginx默认丢弃带下划线的HTTP请求头,需在http或server块中配置underscores_in_headers on启用;启用后头字段原样转发并映射为小写+下划线变量(如X-Api_Key→$http_x_api_key),但存在安全风险,建议优先采用RFC标准命名(如X-Api-Key)。

要让 Nginx 接收并传递带下划线(_)的 HTTP 请求头(例如 X-Api_Key 或 Content_Id),必须显式启用 underscores_in_headers on 指令。Nginx 默认丢弃所有含下划线的请求头,这是出于安全与历史兼容性考虑,并非 bug。
配置位置与生效范围
该指令只能在 http 块或 server 块中设置,不能写在 location 块内:
- 全局启用(推荐):在
nginx.conf的http { }区块内添加一行:underscores_in_headers on; - 按虚拟主机启用:在特定
server { }块中添加相同指令,仅对该 server 生效 - 不支持在 location 中配置,否则会报错 “invalid directive”
启用后 header 的行为变化
开启后,Nginx 不再过滤含下划线的 header,但仍有两个关键细节需注意:
- 原始 header 名称会被保留并原样转发给后端(如 proxy_pass 目标或 FastCGI)
- Nginx 内部变量映射仍遵循小写 + 下划线规则:例如
X-Api_Key→ 可通过$http_x_api_key访问;Content_Id→ 对应$http_content_id - 若同时存在
X-User-ID和X_User_ID,两者都会被接收,但只有后者能生成唯一变量名($http_x_user_id),前者因命名冲突无法映射
配合后端使用的注意事项
即使 Nginx 转发了带下划线的 header,后端服务是否能正确识别,还取决于其运行时实现:
- Node.js、Python(Flask/FastAPI)、Java Spring Boot 一般可直接读取原始 header,无需额外配置
- Go 的
net/http默认将下划线转为连字符,需检查实际接收到的 key 名 - PHP 通过
$_SERVER获取时,仍遵循 RFC 3875:自动转大写、连字符→下划线、加HTTP_前缀(如X-Auth-HMAC→HTTP_X_AUTH_HMAC),但X_Api_Key不会自动变成HTTP_X_API_KEY—— 因为下划线不是标准分隔符,PHP 不做标准化处理,需手动解析getallheaders() - 可用
add_header X-Debug "$http_x_api_key";临时返回响应头,验证是否成功接收
安全与使用建议
虽然功能可用,但生产环境需谨慎对待:
- 不建议在公网暴露的 Nginx 实例上全局开启,尤其当上游服务未做 header 白名单校验时
- 部分 WAF 或 API 网关会将含下划线 header 视为异常流量,可能触发拦截
- 优先推动客户端改用 RFC 合规命名(如
X-Api-Key代替X_Api_Key),这是更可持续的解法 - 若只是临时调试或内部系统对接,开启该选项是快速有效的手段

















