自定义HTTP标头:命名约定


1113

我们的几个用户要求我们在帐户中添加与他们的帐户相关的数据 发送给他们的请求甚至是从API获得的响应 HTTP标头中。就命名格式等而言,添加自定义HTTP标头的一般约定是什么?

另外,请随时在网上发布您偶然发现的这些内容的精巧用法。我们正在尝试使用最好的目标来实现这一目标:)


25
请注意,防火墙可以删除响应头字段。有些删除了RFC 2616(1999年6月,HTTP 1.1)中未提及的所有内容。如果没有新字段,客户端应该仍然可以使用。
stesch 2016年

5
请注意,使用HTTP S时,@ stesch的注释不适用。
–'code_dredd

1
请注意,@ code_dredd的注释是都市传说。防火墙可以过滤HTTPS内容。见howtoforge.com/filtering-https-traffic-with-squidwatchguard.com/help/docs/wsm/xtm_11/en-us/content/en-us/...
stesch

@stesch假定您的文章基本上将代理转换为类似于MiTM的某种东西(它需要加密的客户端连接,然后再建立一个新的客户端连接),然后可以确定,您几乎可以做任何事情,但这实际上抵消了代理PoV的加密b / c它正在解密客户端的内容本身。在这种情况下,从代理的PoV来看,基本上就好像您不是在第
一位

Answers:


1170

该建议 与“X-”开始他们的名字。例如X-Forwarded-ForX-Requested-WithRFC 2047的第5节也提到了这一点。


更新1:2011年6月,发布了IETF的第一稿,以弃用对非标准标头使用“ X-”前缀的建议。原因是当以“ X-”为前缀的非标准头成为标准头时,删除“ X-”前缀会破坏向后兼容性,从而迫使应用程序协议同时支持这两个名称(例如,x-gzipgzip等价)。因此,官方建议是合理地命名它们,不要使用“ X-”前缀。


更新2:从2012年6月开始,不再推荐使用“ X-”前缀作为RFC 6648。以下是相关的引用:

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

...

  1. 不应在参数名称前加上“ X-”或类似的结构。

4.给协议设计者的建议

...

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

  2. 绝对不要规定前缀为“ X-”或类似结构的参数应理解为非标准化的。

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

请注意,“ SHOULD NOT”(“禁止使用”)与“ MUST NOT”(“禁止”)是不同的,有关这些关键字的另一个规范,另请参阅RFC 2119。换句话说,您可以继续使用带有“ X-”前缀的标头,但是现在不再正式推荐它,并且您可能绝对不会像公开标准那样记录它们。


总结

  • 官方建议是明智地命名它们不要使用“ X-”前缀
  • 您可以继续使用带前缀“ X-”的标头,但现在不再正式建议这样做,并且您绝对不能像公开标准那样记录它们

306
就像有很多孩子永远不会成为职业运动员一样,许多自定义标头也永远不会成为标准。我倾向于在这些文字上加上“ X-”。
G-Mac

19
@ G-Mac同意。有这样永远不会结束标准化许多自定义页眉。少数这样做,只需将代码从修改为if (header == "x-gzip")即可if (header == "x-gzip" || header == "gzip")。关于您的类比,这是另一种说法:就像军方所说的“哦,将某人从私人转为将军很麻烦。因此,从现在开始,你们全都是将军。现在我们不需要做太多的工作”
科尔·约翰逊

24
@ColeJohnson不确定该类比是否有效。这里的问题是没有中心点可以更改名称。现在,期望x-gzip的每个代码段都必须更改,或者除了新的标头之外,还需要继续使用旧的标头。最好使用RFC6648。–
vinod

4
@Vinod是的。这样做是有道理的,但是有太多提议的标准永远不会出现。对于文件类型,请确保;删除X-前缀。我反对,但请继续做。对于标题OTOH,请不要将其丢弃。它很容易查看和运行,“哦,这是非标准的;我可以忽略它”与“有那些非标准的标X-头,然后有一个我不认识的标头;我可以安全地忽略它吗?”
科尔·约翰逊

21
尽管cweekly的回答语气不必要地具有防御性,但我相信他是正确的,他的观点解决了此评论主题中说明的问题。简而言之,不要试图确定标题是否会“毕业”;而是确定它是私有还是公共头(特定于应用程序还是“通用” /“全局”)。对于专用标头,可以选择使用X-以确保与公共标头不发生冲突(这要感谢处理公共标头的RFC6648),此外,肯定要使用任意的专用前缀。对于公共标题,请不要X-在任何情况下使用。
tne 2014年

535

该问题需要重读。提出的实际问题与CSS属性中的供应商前缀不同,在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)的供应商的区分就越清晰。

示例:
Google(在各个标准机构中都有一定分量)在–截至2014年1月20日,对我的答案进行了小幅编辑–当前使用“ X-Mod-Pagespeed”表示其Apache模块的版本参与转化给定的响应。是否有人真的建议Google使用不带“ X-”的“ Mod-Pagespeed”,和/或要求IETF祝福其使用?

摘要:
如果您在应用程序内使用自定义HTTP标头(有时是cookie的适当替代方式)来往/自服务器传递数据,并且这些标头显然不打算在您的上下文之外使用在应用程序中,使用“ X-”或“ X-FOO-”前缀对它们进行命名间隔是一种合理且常见的约定。


52
如果我的评论的任何反对者可以解释他们认为反对的部分,我将不胜感激。我不太在乎自己的声誉得分,但我真的很好奇。分歧在哪里?谢谢。
cweekly,2013年

56
我完全同意您的回答,这是唯一回答实际问题的答案。我们在这里谈论的是自定义的,特定于应用程序的标头,永远不要在HTTP标准中对其进行标准化。人们倾向于使用这些约定吗?(例如,以“ _”作为前缀?):(“ _ClientDataFoo”)
Marchy

14
谢谢Marchy,是的,接受的答案未解决所提出的问题。对于非标准(但通用)标头,IETF弃用“ X-”前缀与永远不会标准化的自定义应用程序特定标头无关。以我的观点和经验(webdev的16年)来回答您的问题,最好的约定是使用前面提到的“ X-ACME-ClientData”。“ X-” bc不是标准的(也不是,这就是为什么IETF弃用在这里引起争议的原因),“ ACME-”将其命名为您的“ ACME”公司或特定应用的名称,“ ClientData”可以是任意值您喜欢的语义名称。:)
cweekly 2014年

5
@DarrelMiller ...因此建议使用X-ACMECO-WIDGET-FOO。我坚持认为,对于OP提出的问题,RFC-6648等并未明确禁止使用X-。如果您是一家提供用于其他人的项目的框架,库或模块的供应商,那就另当别论了,并且一定要遵循RFC到T的规定。但这仅适用于单个的一次性应用程序,在该应用程序中自定义特定于应用程序的标头命名约定实际上是完全私有的API。他们将如何与“其他人”的名字发生冲突?那会是谁?
2014年

11
老实说,我有点难以理解RFC推理。可以肯定的是,如果参数已标准化,则将同时存在x版本和非x版本。仅当x版本和非x版本的行为相同时,这才是问题。我在这里偶然发现,是因为我正在向我的API添加“代表”标头。它有一天可能会公开(因为这是一种常见的用例)。如果我使用“ On-Behalf-Of”,并且有一天他们将其添加为标准标头,那么我的语义与标准化标头相同的几率是多少?
fool4jesus 2015年

62

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正确解释,因此在某种程度上,无论是在理论上还是在实践上(尽管这是一个Location标头,其中包含一个URL,并且这些字符在URL中不合法,因此实际上是非法的,但是要遵循不同的规则!)。

就是说,我不会依赖于在所有服务器,代理和客户端上工作的ISO-8859-1,因此出于防御性编程的考虑,我会坚持使用ASCII。


3
较新的HTTP规范RFC7230说:“新定义的标头字段
罗伯特·图珀洛-施内克

23

RFC6648建议您假定自定义标头“可能会标准化,公开,普遍部署或在多个实现中可用”。因此,建议不要在其前面加上“ X-”或类似的结构。

但是,有一个例外“当[您的标头]极不可能被标准化时”。对于此类“特定于实现和私有使用”的标头,RFC表示使用诸如供应商前缀之类的名称空间是合理的。


6
“RFC6648建议您认为您的自定义页眉‘可能趋于规范化,公开,常见的部署,或跨多个实现可用’我认为这给出了一个理由来使用。X-前缀,因为它更可能的东西没有任何前缀可能成为标化。
康拉德

@Konrad如果您假设其他人的相似标头(而不是标头)可能已标准化,则可以避免与发生冲突X-,但这与RFC6648主要采用的假设不同。RFC的例外说明了将来的标准标头与其他供应商的标头之间的潜在冲突,该供应商的技术可能会通过公司合并等方式与您的技术集成在一起。这就是为什么该例外要求供应商前缀的原因。
爱德华·布雷

17

修改(或更正确地说,添加其他HTTP标头)是一个很棒的代码调试工具,如果没有其他要求的话。

URL请求返回重定向或图像时,没有html“页面”可将调试代码的结果临时写入-至少在浏览器中不可见。

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

我定期添加额外的HTTP标头,例如X-fubar-somevar:或X-testing-someresult:进行测试-并发现了很多本来很难跟踪的错误。


2
他为什么要使用这个“标准”?标头的工作原理相同。即使带有“ WHO_EVER_READS_THIS_IS_DUMB_”前缀……
令人难以置信的

16

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

据我所知,没有私有标头的准则。如有疑问,请避免使用。或查看HTTP扩展框架(RFC 2774)。

了解更多的用例将会很有趣;为什么不能将信息添加到邮件正文中?


13
我考虑使用一些自定义标头的主要原因是,这样我就可以做出路由决策而不必解析主体了……
Rozwel 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.