为啥 HTTP 服务器禁止在 HTTP 标头名称中使用下划线

Posted

技术标签:

【中文标题】为啥 HTTP 服务器禁止在 HTTP 标头名称中使用下划线【英文标题】:Why do HTTP servers forbid underscores in HTTP header names为什么 HTTP 服务器禁止在 HTTP 标头名称中使用下划线 【发布时间】:2014-05-16 08:58:21 【问题描述】:

我遇到了一个自定义 HTTP SESSION_ID 标头没有被 nginx 代理传输的问题。

有人告诉我,根据 HTTP RFC,下划线是被禁止的。

搜索,我发现大多数像Apache或nginx这样的服务器在RFC2616第4.2节中将它们定义为非法,其中说:

遵循与 RFC 822 [9] 第 3.1 节中给出的相同的通用格式

RFC822 说:

字段名必须由可打印的 ASCII 字符组成 (即,值介于 33. 和 126. 之间的字符, 小数,冒号除外)

下划线是 ASCII 表中 33-126 范围内的十进制字符 95。

我错过了什么?

【问题讨论】:

【参考方案1】:

它们不是被禁止的,它是 CGI 的遗产。请参阅“Missing (disappearing) HTTP Headers”。

如果你没有显式设置underscores_in_headers on;,nginx 会默默地丢弃带有下划线的 HTTP 标头(根据 HTTP 标准这是完全有效的)。这样做是为了防止在将标头映射到 CGI 变量时出现歧义,因为在该过程中,破折号和下划线都映射到下划线。

【讨论】:

刚刚花了几个小时调试为什么我的 Rails 应用程序在开发中运行良好,但在生产中却不能正常运行:/ 刚刚花了几个小时调试为什么我的 NodeJS 应用程序在开发中运行良好,但在生产中却不能正常运行:/ 刚刚花了几个小时调试为什么我的 Flask 应用程序在开发中运行良好,但在生产中却不能正常运行:/ 回答 Apache 的链接:***.com/questions/17440564/… 刚刚花了 5 分钟调试为什么我的烧瓶应用程序不能在开发或生产中运行,然后幸运地偶然发现了这个线程。呸,躲过了子弹。【参考方案2】:

RFC 7230, sec. 3.2. 允许在标题字段中使用下划线,但不常见。

【讨论】:

以上是关于为啥 HTTP 服务器禁止在 HTTP 标头名称中使用下划线的主要内容,如果未能解决你的问题,请参考以下文章

Zend_Http_Client - 为啥我的 POST 请求发送错误的内容类型标头?

浏览器在 ajax 请求上发送 Origin 标头,但不是通过简单的 HTTP Get 请求。为啥?

Angular:自定义标头被 $http 和 $resource 忽略。为啥?

为啥浏览器中未设置 res 标头中的 cookie?

为啥 HTTP/2 客户端拒绝包含连接头的请求?

如果我在使用 cors 时添加标准 http 标头,为啥会预检请求?