【问题标题】:Custom HTTP headers : naming conventions自定义 HTTP 标头:命名约定
【发布时间】:2011-04-03 10:44:11
【问题描述】:

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

此外,您可以随意发布您在网络上偶然发现的任何智能用法;我们正在尝试使用最好的目标来实现这一点:)

【问题讨论】:

  • 请注意防火墙可以删除响应标头字段。有些删除了 RFC 2616(1999 年 6 月,HTTP 1.1)中未提及的所有内容。如果没有新字段,客户端应该仍然可用。
  • 请注意,@stesch 的评论在使用 HTTPS 时不适用。
  • 请注意@code_dredd 的评论是一个都市传说。防火墙可以过滤 HTTPS 内容。见howtoforge.com/filtering-https-traffic-with-squidwatchguard.com/help/docs/wsm/xtm_11/en-us/content/en-us/…
  • @stesch 鉴于您的文章基本上将代理变成类似于 MiTM 的东西(它需要加密的客户端连接,然后建立一个新的连接),那么可以肯定,您几乎可以做任何事情,但事实否定了这一点来自代理的 PoV b/c 的加密它正在解密客户端的内容本身。在这种情况下,从代理的 PoV 来看,基本上就好像您一开始就没有使用 HTTPS...
  • 如果有人在学术市场上,EzProxy 将去掉自定义标头。您需要编辑 EzProxy 配置以允许它们。之后你必须希望每个成员机构更新他们的 EzProxy 配置。 EzProxy 最常用于校外访问。在过去的几年里一直很流行(出于某种原因/s)

标签: http http-headers


【解决方案1】:

建议 以“X-”开头。例如。 X-Forwarded-ForX-Requested-With。这在 a.o. 中也有提及。 RFC 2047 的第 5 节。


更新 1:2011 年 6 月,发布了第一个 IETF draft,以弃用对非标准标头使用“X-”前缀的建议。原因是当以“X-”为前缀的非标准标头成为标准时,删除“X-”前缀会破坏向后兼容性,迫使应用程序协议支持这两个名称(例如,x-gzipgzip 现在是等效的) .所以,官方的建议是明智地不带“X-”前缀。


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

###3。给新参数创建者的建议

...

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

###4。给协议设计者的建议

...

  1. 不应禁止带有“X-”前缀或类似前缀的参数 被注册的构造。
  1. 不得规定带有“X-”前缀的参数或 类似的结构需要被理解为非标准化的。
  1. 不得规定没有“X-”前缀的参数或 类似的结构需要被理解为标准化。

请注意,“SHOULD NOT”(“不鼓励”)与“MUST NOT”(“forbidden”)不同,另请参阅 RFC 2119 以了解有关这些关键字的另一个规范。换句话说,你可以继续使用以“X-”为前缀的标题,但它不再是官方推荐的,你可能绝对不会将它们作为公共标准来记录。


总结

  • 官方的建议是合理不带“X-”前缀
  • 您可以继续使用以“X-”为前缀的标头,但不再是官方推荐的,而且您绝对不能将它们作为公共标准记录在案

【讨论】:

  • 正如许多孩子永远不会成为职业运动员一样,许多自定义标题永远不会成为标准。我倾向于在那些上保留“X-”。
  • @G-Mac 同意。 so 很多自定义标头永远不会标准化。少数这样做的,只需将代码从if (header == "x-gzip") 编辑到if (header == "x-gzip" || header == "gzip") 就很容易。至于你的比喻,还有一个:就像军方在说“哦,把一个人从私人换成将军很麻烦。所以,从现在开始,你们都是将军。现在我们不需要这样做了很多工作”
  • @ColeJohnson 不确定这个类比是否有效。这里的问题是没有可以更改名称的中心点。现在必须更改需要 x-gzip 的每个 sn-p 代码,或者除了新标头之外还需要继续使用旧标头。最好使用 RFC 6648。
  • @Vinod 是的。这样做是有道理的,但是有这么多提议的标准永远不会出现。对于文件类型,当然;删除 X- 前缀。我反对它,但继续做吧。对于标题OTOH,不要丢弃它。它可以很容易地查看和去,“哦,它是非标准的;我可以忽略它”与“有那些非标准的 X- 标头,然后是我不认识的这个;我可以忽略它吗安全吗?”
  • 虽然cweekly的回答语气是不必要的防御,但我相信他是对的,他的观点解决了这个评论线程中说明的问题。简而言之,不要试图确定一个标题是否会“毕业”;而是确定它是私有标头还是公共标头(特定于应用程序或“通用”/“全局”)。对于私有标头,可选择使用X- 以确保不会与公共标头发生冲突(感谢 RFC6648,它处理公共标头),此外绝对要使用任意私有前缀。对于公共标头,在任何情况下都不要使用X-
【解决方案2】:

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

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

【讨论】:

  • "RFC6648 建议您假设您的自定义标头“可能会变得标准化、公开、普遍部署或可用于多个实现。”我认为这给出了使用 X- 前缀的理由,因为它更多可能没有任何前缀的东西可能会被标准化。
  • @Konrad 如果您假设 其他人的 类似的标头(不是您的标头)可能会标准化,您可以避免与X- 发生冲突,但这是与 RFC6648 不同的假设主要采取。 RFC 的例外说明了未来标准标头与来自其他供应商的标头之间的潜在冲突,该供应商的技术可能通过公司合并等与您的技术集成。这就是例外要求供应商前缀的原因。
  • @EdwardBrey 恕我直言,这种情况(公司合并后的 http 标头冲突等)实际发生的频率是多少?毕竟,使用供应商前缀也不是万无一失的:公司 #1,在其产品 P1 中使用前缀 XY 作为标题 H1,向公司 #2 出售开发人员许可证,公司 #1 破产,他们的 IP 包括品牌名称 XY 是由公司 #3 购买,该公司构建了使用 XY 前缀作为标头 H1 的产品 P3,将该产品开发许可给公司 #2,该公司现在必须集成 2 个产品,但使用相同的标头不兼容。
  • @collapsar RFC 之所以得名,是因为它们是对您的评论类型的请求。您可以检查history 的技术考虑,看看是否考虑了复杂性-兼容性权衡。
【解决方案3】:

这个问题值得重新阅读。提出的实际问题与 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) 标头分开。使用“X-”或“X-ACME-”前缀对于(B)来说是方便和合法的,并且与(A)不冲突。越多的供应商停止在 (A) 中使用“X-”,则 (B) 将变得越清晰。

示例:
谷歌(在各种标准机构中占有一席之地) - 截至今天,20141102 在对我的回答进行了轻微的编辑 - 目前使用“X-Mod-Pagespeed”来指示他们参与的 Apache 模块的版本转换给定的响应。有没有人真的建议谷歌应该使用“Mod-Pagespeed”,没有“X-”,和/或要求 IETF 祝福它的使用?

总结:
如果您在您的应用程序中使用自定义 HTTP 标头(有时作为 cookie 的适当替代品)来向/从您的服务器传递数据,并且这些标头明确地不打算在您的应用程序上下文之外使用,使用“X-”或“X-FOO-”前缀命名它们是合理且常见的约定。

【讨论】:

  • 如果我的评论中有任何反对者可以解释他们认为我的答案的哪一部分令人反感,我将不胜感激。我不太在乎我的声誉得分,但我真的很好奇。分歧在哪里?谢谢。
  • 我完全同意你的回答,这是这里唯一回答实际问题的答案。我们在这里谈论的是自定义的、特定于应用程序的标头,永远不会在 HTTP 标准中标准化。是否存在人们倾向于使用的通用约定? (比如可能在它们前面加上“_”?即:(“_ClientDataFoo”)
  • 谢谢马奇,是的,接受的答案并没有解决所提出的问题。 IETF 弃用非标准(但通用)标头的“X-”前缀与永远不会标准化的自定义应用程序特定标头无关。要回答你的问题,以我的观点和经验(16 年的 webdev),最好的约定是使用前面提到的“X-ACME-ClientData”。 “X-” bc 它不是标准的(也永远不会是,这就是 IETF 弃用在这里没有实际意义的原因),“ACME-”将其命名为您的“ACME”公司或特定应用程序,“ClientData”可以是任何东西你喜欢的语义名称。 :)
  • @DarrelMiller ...因此建议使用 X-ACMECO-WIDGET-FOO。我坚持认为,对于所提出的 OP 问题,RFC-6648 等根本不反对使用 X- 。如果您是提供框架、库或模块以用于其他人的项目的供应商,那就另当别论了,并且一定要遵循 RFC 到 T。但这对于单独的一次性应用程序没有实际意义,其中自定义特定于应用程序的标头命名约定实际上是完全私有的 API。他们将如何与“其他人”的名字发生冲突?那些会是谁?
  • 老实说,我在理解 RFC 推理方面有点困难。当然,如果参数是标准化的,那么将同时存在 x- 和非 x- 版本。如果 x- 和非 x- 版本的行为相同,这只是一个问题。我在这里偶然发现,因为我正在考虑向我的 API 添加一个“代表”标头。它可能有一天会公开(因为它是一种常见的用例)。如果我使用“代表”并且有一天他们将其添加为标准标题,那么我的语义与标准化的语义相同的可能性有多大?
【解决方案4】:

修改,或者更准确地说,添加额外的 HTTP 标头是一个很棒的代码调试工具。

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

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

我经常添加额外的 HTTP 标头,例如 X-fubar-somevar: 或 X-testing-someresult: 来测试结果 - 并且发现了很多原本很难追踪的错误。

【讨论】:

  • 他为什么要使用这个“标准”?标题的工作方式相同。即使带有“WHO_EVER_READS_THIS_IS_DUMB_”前缀......
【解决方案5】:

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           = <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].

所以,有两个结论。首先,很明显标题 name 必须由 ASCII 字符的子集组成 - 字母数字、一些标点符号,而不是其他很多。其次,标题 value 的定义中没有任何内容将其限制为 ASCII 或排除 8 位字符:它明确由八位字节组成,只有控制字符被禁止(注意 CR 和 LF 被考虑控制)。此外,对 TEXT 产生的评论意味着八位字节将被解释为 ISO-8859-1 中的内容,并且存在一种编码机制(顺便说一句,这很可怕)用于表示该编码之外的字符。

因此,为了特别响应@BalusC,很明显,根据规范,标头值在 ISO-8859-1 中。我已经在 Tomcat 的标头中发送了高 8859-1 字符(特别是法语中使用的一些重音元音),并让 Firefox 正确解释了它们,所以在某种程度上,这在实践中和理论上都有效(虽然这是一个 Location 标头,其中包含一个 URL,而这些字符在 URL 中是不合法的,所以这实际上是非法的,但在不同的规则下!)。

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

【讨论】:

  • 较新的 HTTP 规范 RFC7230“新定义的标头字段应将其字段值限制为 US-ASCII 八位字节。”
【解决方案6】:

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

据我所知,没有关于私有标头的准则;有疑问,避免他们。或者查看 HTTP 扩展框架 (RFC 2774)。

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

【讨论】:

  • 我考虑使用一些自定义标头的主要原因是这样我就可以做出路由决策而不必解析正文...
猜你喜欢
  • 2012-10-12
  • 2012-01-17
  • 2012-09-22
  • 2015-05-10
  • 2018-09-26
  • 2011-12-09
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
相关资源
最近更新 更多