如何处理同名的多个cookie?

说例如我有一个应用程序发送以下HTTP标题设置为cookie名为“a”:

Set-Cookie: a=1;Path=/;Version=1 Set-Cookie: a=2;Path=/example;Version=1 

如果我访问/example在服务器上的两个path都是有效的,所以我有两个名为“a”的cookies! 由于浏览器不发送任何path信息,所以两个cookie不能被区分。

 Cookie: a=2; a=1 

应如何处理这个案件? 挑第一个? 用所有的cookie值创build一个列表? 还是应该把这种情况视为开发者的错误?

从SitePoint的这篇文章 :

如果多个相同名称的cookie匹配给定的请求URI,则由浏览器select一个。

path越具体,优先级越高。 但是,基于其他属性(包括域)的优先级未指定,并且可能因浏览器而异。 这意味着如果您已经为“.example.org”和“www.example.org”设置了相同名称的Cookie,则无法确定哪一个会被发回。

编辑:从2010年的这个信息似乎已经过时,看来浏览器现在可以发送多个cookie作为回报,请参阅下面的@Nate的答案以获取详细信息

引用SitePoint上的文章的答案并不完全完整。 请参阅RFC 6265 (公平地说,这个RFC是在发布这个问题后于2011年发布的,它取代了之前从2000年的RFC 2965和1997年的RFC 2109 )。

第5.4节第2小节有这样的说法:

用户代理应该按以下顺序对cookie列表进行sorting:

  • 具有较长path的Cookie在较短path的cookie之前列出。

注意:并不是所有的用户代理都按这个顺序对cookie列表进行sorting,但是这个顺序反映了编写这个文档时的一般做法,并且历史上一直存在服务器(错误地)依赖于这个顺序。

第4.2.2节中也有这个小gem:

…服务器不应该依赖序列化顺序。 特别是,如果Cookie标题包含两个具有相同名称的Cookie(例如,设置了不同的path或域属性),服务器不应该依赖于这些cookie出现在标题中的顺序。

在示例请求cookie( Cookie:a = 2; a = 1 )中,请注意,设置了path/ examplea = 2 )的cookie的path比path为/a = 1 )的path长,首先按照规范的build议发回给你。 因此,假设您可以select第一个值,您或多或less都是正确的。

不幸的是,RFC中使用的语言是非常特殊的 – 使用“ 应该”和“ 不应该在RFC中引入歧义”。 这些表明遵循的惯例,但不要求符合规范。 尽pipe我很了解RFC,但我还没有做过研究,看看真实世界的客户是做什么的; 可能有一个或多个浏览器或其他软件作为HTTP客户端可能不会首先在Cookie:头中发送最长path的Cookie(例如: / example )。

如果您有能力控制cookie的价值,并且想要使您的解决scheme万无一失,那么您最好是:

  1. 使用不同的cookie名称来覆盖某些path,例如:

    • Set-cookie:a-global = 1; Path = /; Version = 1
    • Set-cookie:a-example = 2; Path = / example; Version = 1
  2. 将您需要的path存储在cookie值本身中:

    • Set-cookie:a = 1&path = /; Path = /; Version = 1
    • Set-cookie:a = 2&pat​​h = / example; Path = / example; Version = 1

这两种解决方法都需要服务器上的附加逻辑来select所需的cookie值,方法是将请求的URL与可用的cookie列表进行比较。 这不太漂亮。 不幸的是,RFC没有先知的要求,要求更长的path完全覆盖更短path的cookie(例如:在您的示例中,您将收到Cookie:a = 2 )。

我当然知道应用程序广泛使用多个会话ID来执行此操作,并且似乎一直运行。 但是我不知道 – 也无意发现 – 如果这样做是因为浏览器以一致的顺序返回cookie,这取决于它们的设置时间/设置的path或应用程序是否尝试匹配一个到现有的会话。

我强烈build议避免这种做法。

但是,如果你真的想知道浏览器(和应用程序)如何处理这种情况,为什么不build立一个testing装置并尝试一下。

有多个相同名称的值没有问题…如果你想要他们。 你甚至可以在值中embedded额外的上下文。

如果你不这样做,那么当然,如果你想要两个上下文,不同的名字是一个解决scheme。

另一种方法是使用相同的path(和域)发送相同的cookie名称,即使是更具体的path。 那些设置cookie指令将覆盖该cookie的价值。

现在你知道最重要的部分(他们是如何工作的),并且你可以用几种不同的方式完成你所需要的部分,我对你的问题的回答是:这是一个开发者问题。

如果你需要区分他们,你必须给他们不同的关键价值。