允许Cookie中的字符

这是一个快速:

cookie名称和值中允许的字符是什么? 他们是相同的URL或一些共同的子集?

我问的原因是我最近碰到了一些奇怪的行为,用他们的名字,我只是想知道,如果这是某些浏览器特定的或如果我的代码是错误的cookie。

这是一个快速:

你可能会认为这应该是,但真的不是!

cookie名称和值中允许的字符是什么?

根据古老的Netscape cookie_spec ,整个NAME=VALUEstring是:

一系列字符,不包括分号,逗号和空格。

所以-应该工作,这似乎是确定的浏览器,我在这里; 你在哪里遇到麻烦?

通过以上的暗示:

  • =是合法的,但可能含糊不清。 浏览器总是将string中first =符号的名称和值分开,所以在实践中,可以在VALUE中放置一个=符号,但不能放入NAME。

没有提到,因为Netscape在编写规格时很糟糕,但似乎一直被浏览器支持:

  • NAME或VALUE可能是空string

  • 如果string中没有=符号,浏览器将其视为具有空string名称的cookie,即Set-Cookie: fooSet-Cookie: =foo

  • 当浏览器输出一个空名称的cookie时,他们省略了等号。 所以Set-Cookie: =bar begets Cookie: bar

  • 名称和值中的逗号和空格实际上似乎工作,尽pipe等号周围的空格被修剪

  • 控制字符( \x00\x1F plus \x7F )是不允许的

什么是不提及和浏览器完全不一致,是非ASCII(Unicode)字符:

  • 在Opera和Google Chrome中,它们被编码为UTF-8的Cookie标头;
  • 在IE中,机器的默认代码页被使用(特定于语言环境而不是UTF-8);
  • Firefox(和其他基于Mozilla的浏览器)自己使用每个UTF-16代码点的低字节(所以ISO-8859-1是可以的,但其他任何东西都会被破坏)。
  • Safari只是拒绝发送任何包含非ASCII字符的cookie。

所以实际上你根本不能在cookie中使用非ASCII字符。 如果您想使用Unicode,控制代码或其他任意字节序列,cookie_spec要求您使用您自己select的特别编码scheme,并build议将URL编码(由JavaScript的encodeURIComponent )作为合理的select。

实际标准而言,已经有一些尝试来编码cookie的行为,但到目前为止还没有真实地反映现实世界。

  • RFC 2109试图编译并修复原始的Netscape cookie_spec。 在这个标准中,不允许使用更多的特殊字符,因为它使用RFC 2616标记(a - 仍然允许在那里),只有值可以用带引号的string指定。 没有浏览器实现的限制,引用string和转义的特殊处理,或本规范中的新function。

  • RFC 2965是另外一种方式,整理了2109,并在“版本2cookies”scheme下增加了更多function。 从来没有人执行过任何一个。 这个规范与早期版本有着相同的令牌和引号string限制,这同样也是无意义的负载。

  • RFC 6265是HTML5时代尝试清除历史混乱的尝试。 它仍然不符合现实,但它比早期的尝试好得多 – 至less是浏览器支持的一个合适的子集,而不是引入任何本来可以工作的语法(比如之前的引用string) 。

在6265中,Cookie名称仍然被指定为RFC 2616 token ,这意味着您可以从字母组合中select:

 !#$%&'*+-.^_`|~ 

在cookie值中,它正式禁止(由浏览器过滤)控制字符和(不一致实现的)非ASCII字符。 它保留了cookie_spec禁止空格,逗号和分号的function,加上为了兼容任何实际上实现了早期的RFC的穷人,它也禁止反斜杠和引号,除了引用包含整个值(但在这种情况下,引号仍然被认为是该值,而不是编码scheme)。 所以这给你留下了alphanums加上:

 !#$%&'()*+-./:<=>?@[]^_`{|}~ 

在现实世界中,我们仍然使用原始和最差的Netscape cookie_spec,因此使用cookie的代码应该准备好遇到几乎任何东西,但是对于生成cookie的代码,build议在RFC 6265中使用子集。

在ASP.Net中,您可以使用System.Web.HttpUtility在写入cookie之前安全地对cookie值进行编码,并在读取时将其转换回原始forms。

 // Encode HttpUtility.UrlEncode(cookieData); // Decode HttpUtility.UrlDecode(encodedCookieData); 

这将停止&符号,等于将符号写入cookie中时将值分割成一堆名称/值对。

我认为这通常是浏览器的具体情况。 为了安全起见,base64对JSON对象进行编码,并存储所有内容。 这样你只需要解码它并parsingJSON。 如果不是所有的浏览器,所有在base64中使用的字符都可以正常播放。

较新的rfc6265于2011年4月发布:

 cookie-header = "Cookie:" OWS cookie-string OWS cookie-string = cookie-pair *( ";" SP cookie-pair ) cookie-pair = cookie-name "=" cookie-value cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E ; US-ASCII characters excluding CTLs, ; whitespace DQUOTE, comma, semicolon, ; and backslash 

如果你看@ bobince回答,你会看到更新的限制更严格。

你不能把“;” 在cookie的值字段中,将要设置的名称是string,直到“;” 在大多数浏览器中…

有两个版本的cookies规范
1.版本0cookies又名网景cookies,
2.版本1 aka RFC 2965cookies
在版本0中Cookie的名称和值部分是字符序列,不包括分号,逗号,等号和空格,如果不使用双引号
版本1是复杂得多,你可以在这里查看
在这个版本名称值部分的规格几乎是相同的,除了名称不能以$符号开始

对不起,我无法添加到接受的答案,但我碰到了另一个有趣的问题与IE和Edge。

名称超过1期的曲奇似乎被无声地丢弃了。 所以这工作:

cookie_name_a =值a

而这将会下降

cookie.name.a =值a

这是尽可能less的话 。 专注于不需要转义的angular色:

cookies:

 abdefghijklmnqrstuvxyzABDEFGHIJKLMNQRSTUVXYZ0123456789!#$%&'()*+-./:<>?@[]^_`{|}~ 

对于url

 abdefghijklmnqrstuvxyzABDEFGHIJKLMNQRSTUVXYZ0123456789.-_~!$&'()*+,;=:@ 

对于Cookie和url(十字路口)

 abdefghijklmnqrstuvxyzABDEFGHIJKLMNQRSTUVXYZ0123456789!$&'()*+-.:@_~ 

这就是你如何回答。

请注意,对于Cookie, =已被删除,因为它通常用于设置cookie值。

对于这个URL,这个=被保存了。 十字路口显然没有。

 var chars = "abdefghijklmnqrstuvxyz"; chars += chars.toUpperCase() + "0123456789" + "!$&'()*+-.:@_~"; 

发现转义仍然发生,并意外发生,尤其是在一个Java Cookie环境中,如果cookie遇到最后一个字符,则用双引号将其包装起来。

所以为了安全,只需使用A-Za-z1-9。 这就是我要做的。

几年前,MSIE 5或5.5(也可能是两者)在HTML块中有一个“ – ”的问题,如果你能相信的话。 虽然它没有直接关系,但是我们已经在cookie中存储了一个MD5哈希(仅包含字母和数字),以查找服务器端数据库中的所有其他信息。