自定义HTTP标头:命名约定

我们的一些用户要求我们在其发送的请求的HTTP标头中包含与其帐户相关的数据,甚至包括从我们的API获得的响应。 在命名格式等方面添加自定义HTTP标头的一般惯例是什么?

此外,请随时发布您在网络上偶然发现的任何巧妙用法; 我们正在尝试使用最好的方式来实现这个目标:)


2012年6月,不推荐使用“X-”前缀的建议已经正式成为RFC 6648.下面是相关的引用:

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

...

  • 不应该用“X-”或类似的结构来为它们的参数名称加前缀。
  • 4.对议定书设计者的建议

    ...

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

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

  • 不得规定没有“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>
    

    这个定义取决于两个主要支柱,即令牌和TEXT。 两者在第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作为防御性编程。

    链接地址: http://www.djcxy.com/p/7029.html

    上一篇: Custom HTTP headers : naming conventions

    下一篇: What is the difference between POST and GET?