【问题标题】:Are HTTP headers case-sensitive?HTTP 标头是否区分大小写?
【发布时间】:2025-12-27 17:10:21
【问题描述】:

在一篇博文中,我使用以下 PHP 设置响应的内容类型:

header('content-type: application/json; charset=utf-8');

我刚刚收到对该帖子的评论,说content-type 需要大写,Content-type。它是否正确?它似乎适用于所有小写字母,并且我认为 HTTP 标头不区分大小写。还是只是因为浏览器很好用?

【问题讨论】:

  • 不区分大小写,但如果要修复大小写,则应为“Content-Type”。
  • FWIW,用 application/json 发送“charset”是没有意义的。没有这样的参数。
  • @JulianReschke - 这是错误的,字符集是 Content-Type 标头中的有效参数。见w3.org/International/articles/http-charset/indexdeveloper.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type
  • @NullUserException - 缺点(除了浪费的字节)是继续让人们对 charset 参数感到困惑。只需修复这些组件即可。
  • @JulianReschke 是正确的。 IANA application/json assignment 表示 charset 对于这种媒体类型没有意义。它什么也没做。请不要添加它,因为它会导致不必要的混乱。

标签: http http-headers


【解决方案1】:

标题名称不区分大小写。

来自RFC 2616 - "Hypertext Transfer Protocol -- HTTP/1.1"Section 4.2, "Message Headers"

每个标题字段由一个名称后跟一个冒号 (":") 和字段值组成。字段名称区分大小写

更新的 RFC 7230 在这部分没有列出任何changes from RFC 2616

【讨论】:

  • 答案仍然正确,RFC 7230 声明:“每个标头字段由不区分大小写的字段名称后跟冒号 (":")、可选的前导空格、字段值和可选的尾随组成空格。”
  • 在使用 PHP 使用 'apache_request_headers()' 方法获取标头字段的值时,标头字段区分大小写。
  • 谁能提供在这方面不符合规范的流行浏览器的例子?
  • @Harm 那只是因为 PHP 中的字符串比较是区分大小写的。
  • 对于任何人来说,这里是 RFC 7230 明确指出字段标题应视为不区分大小写的地方:tools.ietf.org/html/rfc7230#section-3.2
【解决方案2】:

HTTP 标头名称不区分大小写,根据 RFC 2616:

4.2:

每个标题字段由一个名称后跟一个冒号 (":") 和字段值组成。字段名称不区分大小写。

(字段可能区分大小写,也可能不区分大小写。)

如果您相信主流浏览器会遵守这一点,那么您就大功告成了。


顺便说一句,与大多数 HTTP 不同,方法(动词)区分大小写:

5.1.1 方法

方法标记表示 在
上执行的方法 由 请求-URI。方法是 区分大小写。

   Method         = "OPTIONS"                ; Section 9.2
                  | "GET"                    ; Section 9.3
                  | "HEAD"                   ; Section 9.4
                  | "POST"                   ; Section 9.5
                  | "PUT"                    ; Section 9.6
                  | "DELETE"                 ; Section 9.7
                  | "TRACE"                  ; Section 9.8
                  | "CONNECT"                ; Section 9.9
                  | extension-method
   extension-method = token

【讨论】:

  • 另一条评论说这个答案已经过时了。真的吗?如果是这样,也许您可​​以更新它,以免人们感到困惑。
  • 使用curl -X put 小写动词会从服务器返回 400 bad request cryptic 错误。过了一段时间才意识到这个动词是无效的。 curl 也没有发出任何警告。 curl -X PUT 通过了。
【解决方案3】:

tldr; HTTP/1.1 和 HTTP/2 标头都不区分大小写。

根据 RFC 7230 (HTTP/1.1):

每个标头字段都包含一个不区分大小写的字段名称 后跟冒号 (":")、可选的前导空格、字段 值和可选的尾随空格。

https://www.rfc-editor.org/rfc/rfc7230#section-3.2

另外,RFC 7540 (HTTP/2):

就像在 HTTP/1.x 中一样,标头字段名称是 ASCII 字符串
以不区分大小写的方式比较的字符。

https://www.rfc-editor.org/rfc/rfc7540#section-8.1.2

【讨论】:

  • 只是澄清一下:字段 names 不区分大小写;字段 可以区分大小写,具体取决于字段名称。
  • 来自 HTTP/2 RFC 的继续引用:“但是,标头字段名称必须在 HTTP/2 中编码之前转换为小写。包含大写标头字段名称的请求或响应必须被视为格式错误(第 8.1.2.6 节)"
  • 我刚刚注意到“必须转换为小写...”部分。这是为什么? CamelCase 在实践中似乎是首选的大小写(开发人员工具、流行的代码库),那么为什么 HTTP/2 会试图违背这一趋势呢?
  • @jimp - 因为标准是关于一致性的 - 使用驼峰式大小写可能会模棱两可 - 尤其是缩写、初始化和首字母缩略词。例如 - 它是“Front-End-Https”还是“Front-End-HTTPS” - “WWW-Authenticate”或“Www-Authenticate” - 指定所有小写字母通过标准化字段来消除歧义。这反过来又简化了对标头的全面处理。
  • @jimp 这可能与 HPACK 有关,HPACK 是 HTTP2 使用的标头压缩算法。如果都是小写,那肯定会更容易。它还有一个小的静态字典:tools.ietf.org/html/rfc7541#appendix-A
【解决方案4】:

header('Content-type: image/png') 不适用于服务于 IE11 的 PHP 5.5,因为图像流显示为文本

header('Content-Type: image/png') 工作,因为图像显示为图像

唯一的区别是大写“T”。

【讨论】:

  • 那么显然这个实现有问题,因为所有的头域都应该被读取为不区分大小写的。 Apache Bench 也搞砸了。它不喜欢小写的字段名称。
【解决方案5】:

它们不区分大小写。实际上 NodeJS 网络服务器 explicitly converts them 是小写的,然后才能在请求对象中使用它们。

这里需要注意的是,所有标题都以 仅小写,无论客户端如何实际发送它们。这 简化了为任何目的解析标头的任务。

【讨论】:

  • 这是因为 node/javascript 是区分大小写的,所以为了简化事情,他们将所有内容标准化为小写,这意味着 HTTP 标头实际上不区分大小写。
【解决方案6】:

HTTP 的 RFC(如上所述)规定标头不区分大小写,但是您会发现对于某些浏览器(我在看您,IE),将每个单词大写往往是最好的:

Location: http://*.com

Content-Type: text/plain

location: http://*.com

content-type: text/plain

这不是“HTTP”标准,而只是浏览器的另一种怪癖,我们作为开发人员必须考虑。

【讨论】:

  • 你能提供任何证据吗?
  • 我的意思是一个具体的测试用例;我确实有一个 IE 可以测试。
  • 为什么它往往是最好的?
  • 我将制作一个浏览器,发送带有随机大写的标题只是为了搞砸开发人员
【解决方案7】:

正式地,标题不区分大小写,但是,通常的做法是每个单词的首字母大写。
但是,因为这是常见的做法,某些程序(如 IE)假定标题是大写的。
所以虽然文档说不区分大小写,但糟糕的程序员基本上已经更改了文档。

【讨论】:

    【解决方案8】:

    Headers 字不区分大小写,但在右侧,如 Content-Type,这样写是个好习惯,因为它区分大小写。就像我下面的例子

    headers = headers.set('Content-Type'
    

    【讨论】: