比如说,我有一个应用程序发送以下HTTP标头设置为名为“a”的cookie:
Set-Cookie: a=1;Path=/;Version=1
Set-Cookie: a=2;Path=/example;Version=1
如果我在服务器上访问/example
这两个路径都有效,那么我有两个名为“a”的cookie!由于浏览器不发送任何路径信息,因此无法区分这两个cookie。
Cookie: a=2; a=1
如何处理此案件?选择第一个?创建一个包含所有cookie值的列表?或者这种情况应该被视为开发人员的错误?
答案 0 :(得分:76)
关于SitePoint的文章的答案并不完整。请参阅RFC 6265(公平地说,此RFC在发布此问题后于2011年发布,取代2000年以前的RFC 2965和1997年的RFC 2109。)
第5.4节第2小节有这样的说法:
用户代理应该按以下顺序对cookie列表进行排序:
- 路径较长的Cookie会在路径较短的Cookie之前列出。
注意:并非所有用户代理都按此顺序对cookie列表进行排序,但这样做 订单反映了撰写本文档时的常见做法,并且, 历史上,有(错误地)依赖的服务器 这个订单。
第4.2.2节中还有这个小宝石:
...服务器不应该依赖序列化顺序。在 特别是,如果Cookie标头包含两个相同的cookie 名称(例如,使用不同的路径或域属性设置), 服务器不应该依赖于这些cookie在标题中出现的顺序。
在您的示例请求Cookie( Cookie:a = 2; a = 1 )中,请注意使用路径 / example 设置的Cookie( a = 2 )的路径比路径 / ( a = 1 )的路径长,所以它首先在线发回给你,这与规范的推荐。因此,在您可以选择第一个值的假设中,您或多或少是正确的。
不幸的是,RFC中使用的语言非常具体 - 使用 SHOULD 和不应该这些词会在RFC中引入歧义。这些表示应该遵循的约定,但不是必需符合规范。虽然我很了解RFC,但我没有做过研究,看看现实世界的客户做了什么;一个或多个充当HTTP客户端的浏览器或其他软件可能无法首先在 Cookie:标头中发送最长路径cookie(例如: / example )。
如果您能够控制cookie的价值并希望使您的解决方案万无一失,那么您最好也是:
使用不同的Cookie名称覆盖某些路径,例如:
在cookie值本身中存储您需要的路径:
通过将请求的URL与可用cookie列表进行比较,这两种解决方法都需要服务器上的其他逻辑来选择所需的cookie值。它不太漂亮。令人遗憾的是,RFC没有先见之明要求更长的路径完全覆盖具有较短路径的cookie(例如:在您的示例中,您将收到 Cookie:a = 2 only < /强>)。
答案 1 :(得分:37)
如果多个同名的cookie与给定的请求URI匹配,则浏览器选择一个。
路径越具体,优先级越高。但是,基于其他属性(包括域)的优先级未指定,并且可能因浏览器而异。这意味着如果您在“.example.org”和“www.example.org”上设置了相同名称的Cookie,则无法确定哪一个会被发回。
编辑:2010年的这些信息似乎已经过时,似乎浏览器现在可以发送多个cookie作为回报,请参阅下面的@Nate回答详情
答案 2 :(得分:0)
我当然知道使用多个会话ID广泛执行此操作的应用程序 - 并且似乎一致地工作。但是我不知道 - 并且无意发现 - 如果他们这样做是因为浏览器以一致的顺序返回cookie,具体取决于它们的设置时间/设置的路径或者应用是否尝试匹配每个一个现有会议。
我强烈建议避免这种做法。
但是,如果你真的想知道浏览器(和应用程序)如何处理这种情况,为什么不建立一个测试装备并试一试。
答案 3 :(得分:0)
为同一个名称设置多个值没有任何问题...如果您需要它们。您甚至可以在值中嵌入其他上下文。
如果你不这样做,那么当然如果你想要两个上下文,不同的名字就是一个解决方案。
另一种方法是使用相同的路径(和域)发送相同的cookie名称,甚至从更具体的路径发送。那些设置的cookie指令将覆盖该cookie的值。
现在您已经了解了最重要的部分(它们如何工作),并且您可以通过几种不同的方式完成所需的工作,我对您的问题的回答是:这是一个开发人员问题。
答案 4 :(得分:0)
如果您使用Java / Scala框架,请执行以下操作:注意!如果请求中包含多个同名Cookie,则Play只会在您的代码中显示其中的1个。
答案 5 :(得分:-1)
如果你需要区分它们,你必须给它们不同的键值。