自定义HTTP标头:命名约定

Jul*_*oux 1051 http http-headers

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

另外,您可以随意发布您在网上偶然发现的任何智能用途; 我们正试图用最好的目标来实现这个目标:)

Bal*_*usC 1100

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-Forwarded-For&X-Requested-With现在等同于).所以,建议只是在没有"X-"前缀的情况下明智地命名它们.


该建议 与"X-"开始他们的名字.例如x-gzip,gzip.这也在RFC 2047的第5节中提到.

  • 正如有许多孩子永远不会成为职业运动员一样,许多自定义标题永远不会成为标准.我倾向于保留"X-". (276认同)
  • @ColeJohnson不确定这个比喻是否有效.这里的问题是你没有中心点可以更改名称.现在必须更改期望x-gzip的每一段代码,或者除了新标头之外还需要继续使用旧标头.最好使用RFC 6648. (21认同)
  • 虽然cweekly答案的语气是不必要的防御,但我相信他是对的,他的观点解决了这个评论主题中所说明的问题.简而言之,不要试图确定标题是否"毕业"; 而是确定它是私有标头还是公共标头(特定于应用程序或"通用"/"全局").对于私有头,可选择使用`X-`以确保不与公共头冲突(感谢RFC6648,它处理公共头),另外肯定使用任意私有前缀.对于公共头文件,在任何情况下都不要使用`X-`. (19认同)
  • @ G-Mac同意.有_so_许多自定义标题永远不会最终标准化.少数几个,很容易编辑你的代码从`if(header =="x-gzip")`到`if(header =="x-gzip"|| header =="gzip")`.至于你的类比,这是另一个:它就像军方说的那样 - "哦,将某人从私人变为将军很麻烦.所以,从现在开始,你们都是将军.现在我们不需要做那么多的工作"_ (16认同)
  • @Vinod是的.这是有意义的,但是有很多提议的标准永远不会被看到.对于文件类型,确定; 删除`X-`前缀.我反对它,但继续做下去.对于标题OTOH,请不要丢弃它.这样可以很容易地看到并且去,"哦,它是非标准的;我可以忽略它"vs"那些非标准的`X-`标题,然后就是这个我不认识的;我可以忽略吗安全吗?" (4认同)
  • @Mr.Cat 实际上,从现在起 5 到 10 年后,我仍然会使用的产品并不多。或者至少我不会使用它们的相同版本。如果您不准备维护一段代码,那很好,但是代码将不再相关。就个人而言,我认为对于非标准化标头最明智的做法是采用 `X-<RAND_NUM>-<NAME>` 的约定,因为,如果两个人想要实现相同的功能,或者共享相同的不同功能“明智”的名字,它们在标准轨道上被消除歧义,并且可以成为标准。 (2认同)

cwe*_*kly 510

这个问题需要重新阅读.问题的实际问题与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) app开发人员将特定于应用程序的字符串传递给客户端和服务器.该规范仅涉及前者(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标准中进行标准化.人们倾向于使用这些常见的约定吗?(比如用"_"作为前缀可能吗?ie :("_ClientDataFoo") (54认同)
  • 我很感激,如果我评论的任何评价者都可以解释我的答案中哪些部分是令人反感的.我对你的声望得分并不在乎,但我真的很好奇.分歧在哪里?谢谢. (48认同)
  • 谢谢Marchy,是的,接受的答案没有解决问题.IETF弃用非标准(但通用)标头的"X-"前缀与永远不会标准化的自定义应用程序特定标头无关.为了回答你的问题,根据我的观点和经验(16年的webdev),最好的惯例是使用前面提到的"X-ACME-ClientData"."X-"bc它不是标准的(也不会是,这就是IETF弃用的原因),"ACME-"将它命名为"ACME"公司或特定应用程序,"ClientData"可以是任何你喜欢的语义名称.:) (13认同)
  • 老实说,理解RFC推理有点麻烦.当然,如果参数是标准化的,那么将有x和非x版本.如果x和非x版本的行为相同,那只是一个问题.我在这里偶然发现,因为我正在寻找为我的API添加"代表"标题.有一天它可能会公开(因为它是一种常见的用例).如果我使用"On-Behalf-Of"并且有一天他们将其添加为标准标题,那么我的语义与标准化语义相同的几率是多少? (11认同)
  • @DarrelMiller ......因此建议使用X-ACMECO-WIDGET-FOO.我坚持认为,对于OP提出的问题,使用X-根本不是RFC-6648之类的禁忌.如果您是供应商提供用于其他人项目的框架,库或模块,这是一个不同的故事,并且无论如何都要遵循RFC到T.但是对于单个一次性应用程序来说,这只是没有实际意义特定于应用程序的标头命名约定实际上是完全私有的API.他们将如何与"其他人"的名字发生冲突?那些是谁的? (5认同)
  • 使用您的公司/产品名称加上标题.x-增加零值,并且通过使用它,你展示了对IETF的无视/无知规范,该规范清楚地表明使用x-前缀是错误的,并且我们从那个错误中学到了. (3认同)
  • 1.从不打算丢弃X-的X-header(假设"X"的预期含义是Xtra或eXtension等)与所谓的标准头一样有效.2.由于对命名的要求很少,_X-_,_Y-_或_Z-_前缀应该都是可以接受的.3.标题通常按字母顺序排列在众所周知的浏览器的"devtools"中,允许devops在一个地方看到一组所有X-header,从而在标准Web服务器标题之上产生一个特定于应用程序的标题的抽象层,用于缓存 - 控制等.人. (3认同)
  • 我喜欢我们可以区分全局但实验性和特定应用程序的想法.但是[RFC6648](https://tools.ietf.org/html/rfc6648)似乎适用于两者; 例如,它声称它''不推荐反对私有,本地,初步,实验或特定于实现的参数的实践,只是反对在这些参数的名称中使用"X-"和类似的结构.'*有人可能认为这是一个错误,但是反对IETF"最佳实践"是不舒服的.出于这个原因,我想我会选择`ACMECO-WIDGET-FOO`而不使用`X-`. (3认同)
  • 根据您的建议,我建议使用类似的约定来封装或命名多种语言的名称,这类似于反向域:`com.mycompany.headers.custom:somevalue`.我找不到任何说你不能在标题名称中使用点的东西.你不会那样碰撞. (2认同)
  • @Conan - 我总是只使用字母,数字和连字符(它们干净地映射到相应的env vars的Apache mod_setenvif下划线),因为在Apache中将标题与env变量配对是我自定义标题的主要用途.因人而异. (2认同)
  • @Darrel Miller,感谢您的评论。如果您显然用其他名称来命名X-前缀,而这些名称绝不会与任何IETF保留/官方名称相冲突,那么您可能就对了,X-前缀本身并不会增加太多价值。(由于规范,使用“ X-”前缀可以有效地保证目标。)现在,我再次重复自己。叹。祝你今天愉快。 (2认同)

Tom*_*son 61

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>
Run Code Online (Sandbox Code Playgroud)

该定义基于两个主要支柱:令牌和TEXT.两者都在第2.2节"基本规则"中定义.令牌是:

   token          = 1*<any CHAR except CTLs or separators>
Run Code Online (Sandbox Code Playgroud)

反过来依靠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
Run Code Online (Sandbox Code Playgroud)

文字是:

   TEXT           = <any OCTET except CTLs,
                    but including LWS>
Run Code Online (Sandbox Code Playgroud)

LWS是线性空白区域,其定义我不会重现,而OCTET是:

   OCTET          = <any 8-bit sequence of data>
Run Code Online (Sandbox Code Playgroud)

该定义附有说明:

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].
Run Code Online (Sandbox Code Playgroud)

那么,有两个结论.首先,很明显,标题名称必须由ASCII字符的子集组成 - 字母数字,一些标点符号,而不是其他许多字符串.其次,标题的定义中没有任何内容将其限制为ASCII或排除8位字符:它明确地由八位字节组成,仅禁止控制字符(注意CR和LF被视为控件).此外,对TEXT产生的评论暗示八位字节将被解释为在ISO-8859-1中,并且存在用于表示该编码之外的字符的编码机制(这是偶然的,可怕的).

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

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

  • 较新的HTTP规范[RFC7230](http://tools.ietf.org/html/rfc7230)说*"新定义的头字段应该将它们的字段值限制为US-ASCII八位字节."* (3认同)

小智 17

修改或更正确地添加额外的HTTP头是一个很好的代码调试工具,如果没有别的.

当URL请求返回重定向或图像时,没有html"页面"暂时将调试代码的结果写入 - 至少不是浏览器中可见的.

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

我经常添加额外的HTTP标头,如X-fubar-somevar:或X-testing-someresult:测试出来的东西 - 并且发现了许多本来很难追查的错误.

  • 他为什么要使用这个“标准”?标头的工作原理相同。即使前缀为“ WHO_EVER_READS_THIS_IS_DUMB _” ... (2认同)

Edw*_*rey 17

RFC6648建议您假设您的自定义标头"可能在多个实现中变得标准化,公共,通常部署或可用".因此,建议不要在其前面加上"X-"或类似的结构.

但是,有一个例外"当你的标题极不可能被标准化时." 对于这种"特定于实现和私有"的头,RFC表示诸如供应商前缀之类的命名空间是合理的.

  • "RFC6648建议您假设您的自定义标头"可能在多个实现中变得标准化,公开,通常部署或可用."我认为这给出了使用`X-`前缀的理由,因为没有任何前缀的东西可能变得更有可能标化. (6认同)
  • @Konrad如果您假设*其他人*的类似标头(而不是您的标头)可能会标准化,您可以避免与“X-”发生冲突,但这与 RFC6648 主要采用的假设不同。RFC 的例外说明了未来标准标头与来自其他供应商的标头之间的潜在冲突,该供应商的技术可能通过公司合并等方式与您的技术集成。这就是例外要求供应商前缀的原因。 (2认同)

Jul*_*hke 16

头字段名称注册表在RFC3864中定义,并且"X-"没有什么特别之处.

据我所知,私有标题没有指导原则; 有疑问,避免它们.或者查看HTTP扩展框架(RFC 2774).

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

  • 我正在考虑一些自定义标题的主要原因是我可以做出路由决策而无需解析正文...... (12认同)