cookie 的名称是不是区分大小写?

Posted

技术标签:

【中文标题】cookie 的名称是不是区分大小写?【英文标题】:Is the name of a cookie case sensitive?cookie 的名称是否区分大小写? 【发布时间】:2012-07-03 22:37:42 【问题描述】:

HTTP Cookie 由名称-值对组成,并且可以由服务器使用此响应设置:

HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: name=value
Set-Cookie: name2=value2; Expires=Wed, 09 Jun 2021 10:18:14 GMT

来自客户端的未来请求将如下所示:

GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: name=value; name2=value2

cookie 的名称是否区分大小写?

例如,如果我的服务器发送这样的响应:

HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: Aaaa=Bbbb
Set-Cookie: aAaa=bBbb
Set-Cookie: aaAa=bbBb
Set-Cookie: aaaA=bbbB

期望客户端(Chrome、FireFox、Safari、IExplorer、Opera 等)在未来发送带有标头 Cookie: Aaaa=Bbbb; aAaa=bBbb; aaAa=bbBb; aaaA=bbbB; 的请求是否合理?

注意:问题既不是 JSP 特定的、php 特定的,也不是 ASP 特定的。

【问题讨论】:

@lanzz,RFC 并不总是那么清楚......所以提出问题以确认一种或另一种方式是个好主意。不仅如此,我们可以在下面看到有一个答案引用了 MSDN,其中有一句话说明 cookie 名称不区分大小写! @AlexisWilke 我同意 RFC 有时含糊不清,但大多数时候它们都非常可读和简洁。 OP 没有提供阅读过 RFC 的证据根本,更不用说被它混淆了。 MSDN不是 HTTP cookie 的权威来源。 【参考方案1】:

似乎 cookie 实际上是区分大小写的。对此有些困惑。有趣的是,MSDN 另有说法:

Cookie 名称不区分大小写

来源:http://msdn.microsoft.com/en-us/library/ms970178.aspx 文章底部说它是©2002,所以它可能已经过时了。

此外,asp.net 论坛中也有人问过这个问题:http://forums.asp.net/t/1170326.aspx?Are+cookie+names+case+sensitive+,而且答案似乎区分大小写。

发生了什么事? MSDN 说不,其他技术说是。可以肯定的是,我使用 ASP Classic 对此进行了测试。

代码

hashUCASE = Request.Cookies("data")("Hash")
hashLCASE = Request.Cookies("data")("hash")

Response.Write "<p> hashUCASE = " & hashUCASE
Response.Write "<br> hashLCASE = " & hashLCASE


cookieNameUCASE = Request.Cookies("Data")
cookieNameLCASE = Request.Cookies("data")

Response.Write "<p> cookieNameUCASE = " & cookieNameUCASE
Response.Write "<br> cookieNameLCASE = " & cookieNameLCASE

Response.End

结果

hashUCASE: EE3305C0DAADAAAA221BD5ACF6996AAA
hashLCASE: EE3305C0DAADAAAA221BD5ACF6996AAA

cookieNameUCASE: name=1&Hash=EE3305C0DAADAAAA221BD5ACF6996AAA
cookieNameLCASE: name=1&Hash=EE3305C0DAADAAAA221BD5ACF6996AAA

正如您在结果中看到的那样,值“Hash”是用大写字母创建的,即使您使用小写字母发出请求,它也会返回相同的值,这使得它不区分大小写。在这种 MS 技术下,它不是。

结论

因此,在 ASP 经典中使用 Request.Cookies(),它区分大小写,就像 Microsoft 所说的那样。但是等等,它不是又区分大小写了吗?这可能意味着是否敏感取决于向浏览器发出请求的服务器端技术,这可能会规范化 cookie 名称以发出请求,从而使其不区分大小写。但这是我们必须测试以验证的其他内容。

我的建议是使用您使用的任何技术进行测试,并在您的代码库中建立标准,与您的团队达成协议。即,如果您要使用 cookie,请决定在您要在代码中使用它的任何时候它是否总是以小写或大写形式编写。这样就不会有任何区分大小写的问题,因为在您的代码中它总是以相同的大小写声明。

tl;博士

只要您对 cookie 名称保持约定,您就不会有区分大小写的问题。

【讨论】:

这不是一个 ASP 问题...由于我们显然无法决定用户将使用哪些浏览器,因此我们不能只规定 cookie 区分大小写(如果它们不区分大小写)(或反之反之亦然)。 @Pacerier 没错,这就是我在上一段中提出的观点。制定一个始终使用小写的约定就是一个例子,并且总是测试你的东西。【参考方案2】:

底部是一个脚本,用于在浏览器和 .Net 框架上演示 Cookie 区分大小写。每次运行时,都会插入一个名为 xxxxxxxxxx 的 cookie,大小写随机。按 F5 刷新几次以插入一些 cookie。

我在 Chrome 和 Firefox 上测试过,两者都表现出类似的行为,如下所示:

Request.Cookies["xxxxxxxxxx"].Name returns: xxxxXxXXXX
All XXXXXXXXXX Cookies:

    xxxxXxXXXX
    xXxxXxXXXx
    XxxxxXxXXx
    XXXxXxXXxX

它显示:

Cookie 在 Chrome 和 Firefox 上区分大小写 .Net Framework 可以处理区分大小写的 cookie(这就是它可以循环遍历所有这些 cookie 的原因) Request.Cookies["xxxxxxxxxx"] 不区分大小写(这就是为什么它返回第一个不区分大小写匹配名称的 cookie)

正如其他答案中提到的,新的 RFC 表明 cookie 区分大小写,Chrome 和 Firefox 似乎都以这种方式处理它。 .Net Framework 可以处理区分大小写的 cookie,但它确实希望不区分大小写地处理 cookie,并且它的许多函数确实以这种方式处理 cookie(Cookies[]、Cookies.Set() 等)。这种不一致会导致许多难以跟踪的错误。

TestCookie.aspx:

<%@ Page language="c#" AutoEventWireup="false" validateRequest=false %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title id="title">Test Cookie Sensitivity</title>
</head>
<body>
<p>Request.Cookies["xxxxxxxxxx"].Name returns:
<%
    HttpCookie cookie2 = Request.Cookies["xxxxxxxxxx"];
    if (cookie2 == null) Response.Write("No cookie found");
    else Response.Write(cookie2.Name);
%>
</p>
<h3>All XXXXXXXXXX Cookies:</h3>
<ul>
<%
    foreach (string key in Request.Cookies.Keys)
        if (key.ToLower() == "xxxxxxxxxx") Response.Write("<li>" + key + "</li>");
    Random rand = new Random();
    StringBuilder name = new StringBuilder();
    for (int i = 0; i < 10; i++) 
        if (rand.Next(2) == 0) name.Append('x');
        else name.Append('X');
    
    HttpCookie cookie = new HttpCookie(name.ToString());
    cookie.HttpOnly = true;
    cookie.Expires = DateTime.Now.AddMonths(1);
    Response.Cookies.Add(cookie);
%>
</ul>
</body>
</html>

【讨论】:

这可能只是 .NET api 的问题,与 HTTP 标准无关... 当然可以。除了其他答案中的 RFC 讨论之外,我只想提供一些确认的结果,以便我们了解浏览器的行为方式,以及 .NET 的奇怪行为如何让我陷入困境(并可能让其他人陷入困境)。【参考方案3】:

根据RFC 2109 - HTTP State Management Mechanism cookie 名称又名属性名称不区分大小写

4.1 语法:通用

Set-Cookie 和 Cookie 这两个状态管理头有共同的 涉及属性值对的句法属性。下列 语法使用符号和标记 DIGIT(十进制数字)和 令牌(非正式地,一个非特殊的、非空白的序列 字符)来自 HTTP/1.1 规范 [RFC 2068] 来描述 它们的语法。

av-pairs        =       av-pair *(";" av-pair)
av-pair         =       attr ["=" value]        ; optional value
attr            =       token
value           =       word
word            =       token | quoted-string

属性(名称)(attr)不区分大小写。空格是 令牌之间允许。请注意,虽然上面的语法 description 将 value 显示为可选,大多数 attrs 都需要它们。

【讨论】:

这与 Ianzz 的回答有何匹配? RFC 2109 已被RFC 6265 通过RFC 2965 废弃; RFC 6265 不包括您引用的定义。 我推测,出于区分大小写的原因,在后来的 RFC 中有意删除了 cookie 名称与属性名称的混淆。 根据MSDN,.net 仍然遵循 RFC 2109 - 在解析 HTTP 响应标头期间支持以下 cookie 格式:原始 Netscape 规范、RFC 2109 和 RFC 2965 这也可以在.net sources中看到【参考方案4】:

Cookie 名称区分大小写。 RFC 没有明确说明,但每个大小写不区分比较都明确说明,并且没有关于 cookie 名称的明确说明。 Chrome 和 Firefox 都将 cookie 视为区分大小写的,并将所有大小写变体保留为不同的 cookie。

测试用例(PHP):

print_r($_COOKIE);

setcookie('foo', '123');
setcookie('Foo', '456');

两次加载脚本,第二次运行时观察$_COOKIE转储。

【讨论】:

@PeerStritzinger 我无法理解您的评论,或者您实际上没有阅读我的答案。我在 RFC 中找不到具有这种效果的 explicit 语句,但我对它的解释与您所说的完全相同:cookie 名称区分大小写 .如果您确实在 RFC 中找到了关于此的明确声明,欢迎您分享您的发现,但我觉得您对我的回答投反对票并声称它是错误的,然后您实际上同意它。 @Pacerier Peer 引用了一个过时的 RFC。 RFC 2109 已被 RFC 2965 淘汰,而 RFC 6265 又已淘汰。 @Pacerier 不,我是说它们不再不区分大小写。旧的 RFC 使用与属性名称相同的规则来描述它们,不区分大小写;当前的 RFC 没有以相同的方式定义它们,并且没有将 cookie 名称明确描述为不区分大小写。使用我的示例 PHP 代码在 Chrome 和 Firefox 中很容易证明区分大小写;由于两个主要浏览器都将它们视为区分大小写,因此您别无选择,只能确保您也将它们视为区分大小写,否则会破坏与 FF 和 Chrome 的兼容性。 RFC 所说的完全无关紧要!我们编写代码以在当今使用的浏览器上运行:IE、Firefox、Chrome。由于我们的代码必须工作,我们必须只关心浏览器是如何实现的。而且我可以说至少 Internet Explorer 是区分大小写的,所以我们应该将 cookie 视为区分大小写以避免出现问题! 阅读我的回答了吗? 所有主要浏览器都以区分大小写的方式处理cookie名称,因为这是RFC中规定的。您是在告诉我 RFC 无关紧要,因为您发现至少 Internet Explorer 实际上遵循它?更不用说如果您的代码以区分大小写的方式处理cookie,那么浏览器也这样做并不重要;如果您将它们处理为不区分大小写但浏览器区分大小写,则情况并非如此。【参考方案5】:

根据MSDN,cookie 名称不区分大小写。但是,我不确定这是否只是 ASPX/IIS 特定的实现。我相信这也取决于网络服务器和语言。

如果您发送一个名为“UserID”的 cookie,浏览器会确保将其作为“UserID”而不是“userid”发回。

【讨论】:

是的,我想知道它是否也只是一个 ASPX 实现:forums.asp.net/t/1170326.aspx/1

以上是关于cookie 的名称是不是区分大小写?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 cookie 路径区分大小写?

如果按名称搜索,如果列上有索引,是不是需要使列(字符串)对 EF Core 查询区分大小写?

BigQuery 中的函数名称区分大小写

sql语法有没有区分大小写?

磁盘 ID 中的资源组名称不区分大小写

Spark Cassandra 使用区分大小写的名称写入 UDT 失败