自定义HTTP标头:命名约定

我们的一些用户要求我们在他们的账户中包含与他们账户相关的数据,甚至包括来自我们的API的回复。 在命名格式等方面添加自定义HTTP头的一般惯例是什么?

另外,请随意发布您在网络上偶然发现的任何巧妙用法; 我们正在尝试使用什么是最好的那里作为一个目标:)

2012年6月,建议使用“X-”前缀的做法已经正式成为RFC 6648 。 以下是相关的引用:

3.对新参数创建者的建议

  1. 不应该用“X-”或类似的结构来为它们的参数名加上前缀。

4.对议定书设计者的建议

  1. 不应该禁止带有“X-”前缀或类似结构的参数被注册。

  2. 不得规定带有“X-”前缀或类似结构的参数需要被理解为非标准化的。

  3. 不得规定没有“X-”前缀或类似结构的参数需要被理解为标准化的。

请注意,“不应该”(“不鼓励”)与“禁止”(“禁止”)不同,另请参阅RFC 2119关于这些关键字的其他规范。 换句话说,您可以继续使用“X-”前缀标题,但不建议使用这种标题,并且不得将它们记录为公共标准。


2011年6月,发布了第一份IETF草案 ,以反对对非标准标题使用“X-”前缀的建议。 原因是当以“X-”为前缀的非标准头文件变为标准时,删除“X-”前缀会破坏向后兼容性,迫使应用程序协议同时支持这两个名称(例如, x-gzipgzip现在等同)。 所以,建议只是将它们合理地命名而不用“X-”前缀。


建议用“X-”开始他们的名字。 例如X-Forwarded-ForX-Requested-With 。 在RFC 2047的第5节中也提到了这一点。

这个问题需要重新阅读。 被问到的实际问题与CSS属性中的供应商前缀不相似,在这里,供应商支持和官方标准的前瞻性和考虑是合适的。 问的实际问题更类似于选择URL查询参数名称。 没有人应该关心他们是什么。 但是,定制名称是一个非常有效而且普遍的正确的事情。

理由:
它是关于定制的,特定于应用的头文件的开发者惯例 – “ 与其账户相关的数据 ” – 与供应商,标准组织或由第三方实施的协议无关,除了所讨论的开发人员只需要避免服务器,代理或客户端可能有其他打算使用的头名称。 出于这个原因,给出的“X-Gzip / Gzip”和“X-Forwarded-For / Forwarded-For”示例是没有意义的。 提出的问题是关于私有API的约定,类似于URL查询参数命名约定。 这是一个偏好和名称空间的问题; 任何代理或供应商没有“X”支持的“X-ClientDataFoo”的担忧显然是错误的。

“X-”前缀没有什么特别或不可思议的地方,但有助于明确它是一个自定义标题。 事实上,RFC-6648等人帮助支持使用“X-”前缀的情况,因为 – 作为HTTP客户端和服务器的供应商放弃前缀 – 您的应用特定的私有API,个人数据 – 传递机制变得更好 – 与少量官方保留标题名称的名称空间冲突绝缘。 也就是说,我个人的偏好和建议是更进一步,例如“X-ACME-ClientDataFoo”(如果你的小部件公司是“ACME”)。

恕我直言,IETF规范对回答OP的问题还不够具体,因为它没有区分完全不同的用例:(A)供应商一方面引入了新的全球适用的功能,如“Forwarded-For”,另一方面与(B)应用程序开发人员将应用程序特定字符串传递给客户机和服务器 (A)。这个规范只关注前者。 这里的问题是(B)是否有公约。 有。 它们涉及将这些参数按字母顺序组合在一起,并将它们与类型(A)的许多与标准相关的标题分开。 (B)使用“X-”或“X-ACME-”前缀是方便和合法的,并且不与(A)冲突。 (A)停止使用“X-”的厂商越多,(B)将变得越清晰。

例:
谷歌(在各个标准组织中占有一席之地)是,截至今天,20141102在我的回答的这个轻微的编辑中 – 目前使用“X-Mod-Pagespeed”来表示他们的Apache模块的版本转化给定的回应。 有人真的建议谷歌应该使用“Mod-Pagespeed”,没有“X-”,和/或要求IETF祝福它的使用?

概要:
如果您在您的应用程序中使用自定义HTTP标头(作为Cookie的一个有时适合的替代方法)来将数据传递到您的服务器或从您的服务器传递数据,而且这些标头显然不是意图在应用程序的上下文之外使用,名称 – 将它们与“X-”或“X-FOO-”前缀间隔是一个合理而常见的约定。

HTTP标头的格式在HTTP规范中定义。 我将要讨论HTTP 1.1,规范是RFC 2616 。 在第4.2节“消息头”中定义了头的一般结构:

  message-header = field-name ":" [ field-value ] field-name = token field-value = *( field-content | LWS ) field-content = <the OCTETs making up the field-value and consisting of either *TEXT or combinations of token, separators, and quoted-string> 

这个定义取决于两个主要支柱,即令牌和文本。 在2.2节,“基本规则”中对这两者进行了定义。 令牌是:

  token = 1*<any CHAR except CTLs or separators> 

依靠CHAR,CTL和分离器:

  CHAR = <any US-ASCII character (octets 0 - 127)> CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)> separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT 

TEXT是:

  TEXT = <any OCTET except CTLs, but including LWS> 

LWS是线性空白空间,其定义我不会再现,而OCTET是:

  OCTET = <any 8-bit sequence of data> 

这个定义有一个附注:

 The TEXT rule is only used for descriptive field contents and values that are not intended to be interpreted by the message parser. Words of *TEXT MAY contain characters from character sets other than ISO- 8859-1 [22] only when encoded according to the rules of RFC 2047 [14]. 

所以,有两个结论。 首先,很明显,标题名称必须由ASCII字符的子集构成 – 字母数字,标点符号,而不是其他标点符号。 其次,标题的定义中没有任何内容将其限制为ASCII或排除8位字符:它明确地由八位字节组成,只有控制字符被禁止(注意CR和LF被认为是控制)。 此外,关于TEXT制作的评论意味着八位字节被解释为在ISO-8859-1中,并且存在用于表示编码之外的字符的编码机制(这是偶然的)。

所以,要特别回复@BalusC,很明显的是根据规范,标题值在ISO-8859-1中。 我已经在Tomcat的头文件中发送了高8859-1个字符(特别是一些法语中使用的重音元音),并通过Firefox正确解释了它们,所以在某种程度上,这在实践中以及在理论上都是有效的(虽然这是一个位置标题,其中包含一个URL,这些字符在URL中是不合法的,所以这实际上是非法的,但根据不同的规则!)。

也就是说,我不会依赖ISO-8859-1在所有服务器,代理和客户端上工作,所以我坚持使用ASCII作为防御性编程。

头字段名称注册表在RFC3864中定义,没有什么特别的“X-”。

据我所知,没有私人标题的指导方针; 有疑问,避免它们。 或者看看HTTP Extension Framework( RFC 2774 )。

了解更多的用例将是有趣的。 为什么不能将信息添加到消息体?

修改,或者更正确地说, 添加额外的HTTP头是一个伟大的代码调试工具,如果没有别的。

当一个URL请求返回一个重定向或者一个图像时,没有html页面来临时将调试代码的结果写入到 – 至少不是在浏览器中可见的。

一种方法是将数据写入本地日志文件,稍后再查看该文件。 另一种方法是暂时添加反映正在调试的数据和变量的HTTP标头。

我经常添加额外的HTTP头文件,比如X-fubar-somevar:或者X-testing-someresult:来测试一些东西,并且发现了许多本来很难追踪的bug。