【问题标题】:Set more than one HTTP header with the same name?设置多个具有相同名称的 HTTP 标头?
【发布时间】:2011-03-15 13:19:30
【问题描述】:

据我所知,HTTP 规范允许设置多个具有相同名称的 HTTP 标头。有没有这样做的用例(从客户端到服务器,反之亦然)?

HTTP 1.1 Section 4.2:

多个消息头字段 相同的字段名可能出现在 当且仅当整个消息 该标头字段的字段值是 定义为逗号分隔的列表 [即,#(值)]。必须是可能的 组合多个标题字段 成一个“字段名:字段值” 对,不改变语义 的消息,通过附加每个 第一个的后续字段值, 每个用逗号分隔。命令 在哪些头字段中具有相同的 因此,收到的字段名是 意义重大的解释 组合的字段值,因此 代理不得更改 消息时的这些字段值 转发。

如果我没记错的话,没有需要多个同名标题的情况。

【问题讨论】:

  • "如果我没记错的话,就没有需要多个同名标题的情况。" -- 你是对的,根据你和原始标题之间的技术,我不会指望它得到适当的支持。
  • 我唯一一次看到重复的标题是Set-Cookie:
  • 相关问题:Are Duplicate HTTP Response Headers acceptable?。 WebDAV 标头是 another example 的标头名称重复。

标签: http http-headers


【解决方案1】:

通常用于Set-Cookie:。许多服务器设置了多个 cookie。

当然,您总是可以将它们全部设置在一个标题中。

实际上,我认为你不能在一个标头中设置多个 cookie。所以这是一个必要的用例。

Cookie 规范 (RFC 2109) 确实声称您可以将多个 cookie 组合在一个标头中,就像其他标头可以组合(逗号分隔)一样,但它也指出不符合标准的语法(例如 @987654338 @ 参数,它的值中有,s)仍然很常见,必须由实现来处理。

因此,如果您在 Set-Cookie 标头中使用 Expires 参数并且您不希望所有 cookie 同时过期,您可能需要使用多个标头。

更新:Cookie 规范的演变

RFC 2109 已被RFC 2965 淘汰,而RFC 6265 又被RFC 6265 淘汰,这在问题上更为严格:

源服务器不应将多个 Set-Cookie 标头字段折叠成单个标头字段。折叠 HTTP 标头字段的常用机制(即,在 [RFC2616] 中定义)可能会更改 Set-Cookie 标头字段的语义,因为 Set-Cookie 在与此类折叠冲突的方式。

旁注

RFC 6265 使用动词“folding”来指代将多个标头字段组合为一个,这在 HTTP/1 规范的上下文中是模棱两可的(RFC2616 和它的继任者 RFC 7230) 其中:

  • "folding" 始终指行折叠,并且

  • 动词“combine”用于描述合并相同的头部。

组合标题字段

  • 请参阅RFC 2616, Section 4.2, Message Headers(在问题中引用),但搜索单词“combine”会出现特殊情况。

  • 以上项目被RFC 7230, Section 3.2.2, Field Order淘汰:

    接收者可以将多个具有相同字段名称的标头字段组合成一对field-name: field-value,而不改变消息的语义,方法是将每个后续字段值按顺序附加到组合的字段值上,用逗号分隔。因此,接收具有相同字段名称的头字段的顺序对组合字段值的解释很重要;转发消息时,代理不得更改这些字段值的顺序。

    注意:在实际应用中,“Set-Cookie”头域(RFC6265)在响应消息中经常出现多次且不使用列表语法,违反了上述对多个同名头域的要求。由于它不能组合成单个字段值,因此收件人在处理标头字段时应将Set-Cookie 作为特殊情况处理。 (详情请参阅 [Kri2001] 的 Appendix A.2.3。)

折线

  • 来自RFC 2616, Section 2.2, Basic Rules

    如果续行以空格或水平制表符开头,则 HTTP/1.1 标头字段值可以折叠到多行。所有线性空白,包括折叠,都具有与 SP 相同的语义。在解释字段值或向下游转发消息之前,接收者可以用单个 SP 替换任何线性空白。

  • 以上部分已被RFC 7230, Section 3.2.4, Field Parsing废止:

    从历史上看,HTTP 标头字段值可以扩展为多行,方法是在每一行之前至少使用一个空格或水平制表符 (obs-fold)。除了message/http 媒体类型 (Section 8.3.1) 之外,本规范不赞成这种行折叠。发件人不得生成包含行折叠的消息(即,具有包含与 obs-fold 规则匹配的任何字段值)的消息,除非该消息旨在包装在 message/http 媒体类型中。

    在不在message/http 容器内的请求消息中接收到obs-fold 的服务器必须通过发送 400 (Bad Request) 拒绝该消息,最好使用说明过时的行折叠是不可接受的表示,或在解释字段值或向下游转发消息之前,将每个收到的obs-fold 替换为一个或多个 SP 八位字节。

    在不在 message/http 容器内的响应消息中接收obs-fold 的代理或网关必须丢弃该消息并将其替换为 502 (Bad Gateway) 响应,最好使用解释说明的表示接收到不可接受的行折叠,或在解释字段值或向下游转发消息之前将每个接收到的 obs-fold 替换为一个或多个 SP 八位字节。

    在响应消息中接收到obs-fold 且不在message/http 容器内的用户代理必须在解释字段值之前将每个接收到的obs-fold 替换为一个或多个SP 八位字节。

【讨论】:

  • 您可以轻松地将它们设置在一个标题中: Set-Cookie: hello=world;概念=证明
  • 啊,但是你能在同一个Header中设置不同期限的cookie吗?说,你能把它转换成一个标题吗?设置 Cookie:name1=value1;过期=2012 年 2 月 22 日星期三 17:45:00 GMT Set-Cookie: name2=value2;过期=格林威治标准时间 2021 年 6 月 9 日星期三 10:18:14
  • 这将在浏览器中保存一个名为 Expires 的 cookie 并被第二个覆盖...,同时我已经构建了一个服务器端会话后端,100% 安全,超级简单和节省可能的 Java 对象
  • 不,Expires 有特殊含义,就像 Path、Secure、Domain 等(参见ietf.org/rfc/rfc2109.txt)。例如,查看此页面的 HTTP 标头,我看到:“Set-Cookie:usr=t=[redacted]; domain=.stackoverflow.com; expires=Fri, 12-Oct-2012 23:27:03 GMT ; 路径=/; HttpOnly”。我认为所有这些限定符(域、过期、路径和 HttpOnly)都必须适用于此标头中设置的所有 cookie。
【解决方案2】:

由于重复的标头可能会导致各种 Web 服务器和 API 出现问题(无论规范怎么说),我怀疑是否存在任何通用用例,这是最佳实践。当然,这并不是说某个地方的某个人没有这样做。

【讨论】:

  • 内容安全策略旨在处理多个标题。请参阅twitter.com/mikewest/status/841892857736765443 了解这会导致问题的位置。
  • 某些标题是要复制的。自最初发布此答案以来,这些标头(例如,Link)的数量和流行程度有所增加,但即便如此,发送多个 Set-Cookie 标头也很常见。
【解决方案3】:

当您正在寻找用例时,Accept 可能是一个有效的用例。

  • 接受:应用程序/json
  • 接受:应用程序/xml

【讨论】:

    【解决方案4】:

    仅允许使用非常特定格式的标题,请参阅RFC 2616, Section 4.2

    【讨论】:

    • 他在问题中非常清楚地表示,他意识到这是允许的,这不是他要问的。
    • 该链接非常有用。特别是标题出现多次的部分,也必须能够表示为具有逗号分隔值的单个标题。
    【解决方案5】:

    旧线程,但我正在研究同样的问题。无论如何,Accept 和 Accept-Encoding 标头是使用多个值的典型示例,以逗号分隔。即使这些是特定于请求的标头,规范也不会在此级别区分请求和响应。检查此页面中的那个。 规范说的是,如果您在标头的值中使用逗号作为字符,则不能使用多个同名标头,除非您消除了逗号的使用歧义。

    【讨论】:

      猜你喜欢
      • 2021-11-24
      • 1970-01-01
      • 1970-01-01
      • 2012-08-30
      • 2011-09-25
      • 2015-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多