Cookie 名称和值中允许使用哪些字符?它们与 URL 或某些公共子集相同吗?
我问的原因是我最近遇到了一些奇怪的 cookie 行为,这些行为-
以他们的名字命名,我只是想知道这是否是特定于浏览器的,或者我的代码是否有问题。
根据古老的网景cookie_spec整个NAME=VALUE
字符串是:
不包括分号、逗号和空格的字符序列。
So -
应该可以,而且在我这里的浏览器中似乎确实没问题;你在哪里遇到麻烦了?
由上述含义可知:
-
=
包含在内是合法的,但可能存在歧义。浏览器总是首先分割名称和值=
字符串中的符号,所以在实践中你可以放一个=
VALUE 中包含符号,但 NAME 中不包含符号。
没有提到的是,因为 Netscape 在编写规范方面很糟糕,但似乎一直受到浏览器的支持:
-
NAME 或 VALUE 可以是空字符串
-
如果没有=
字符串中根本没有符号,浏览器将其视为具有空字符串名称的cookie,即Set-Cookie: foo
是相同的Set-Cookie: =foo
.
-
当浏览器输出一个空名称的 cookie 时,它们会省略等号。所以Set-Cookie: =bar
begets Cookie: bar
.
-
名称和值中的逗号和空格实际上似乎有效,尽管等号周围的空格被修剪
-
控制字符(\x00
to \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 要求您使用您自己选择的临时编码方案并建议 URL 编码(由 JavaScript 的生成)encodeURIComponent
)作为合理的选择。
按照actual标准中,已经有一些尝试将 cookie 行为编入法典,但迄今为止还没有真正反映现实世界。
-
RFC 2109是对原始 Netscape cookie_spec 进行编码和修复的尝试。在此标准中,不允许使用更多特殊字符,因为它使用RFC 2616代币(一个-
is still允许),并且只有该值可以在带有其他字符的带引号的字符串中指定。没有浏览器实现过这些限制、带引号的字符串和转义的特殊处理或本规范中的新功能。
-
RFC 2965这是另一个尝试,整理了 2109 并在“版本 2 cookie”方案下添加了更多功能。也没有人实施过任何这些。该规范与早期版本具有相同的标记和引用字符串限制,并且同样是一堆废话。
-
RFC 6265是 HTML5 时代清理历史混乱的一次尝试。它仍然与现实不完全匹配,但它比早期的尝试要好得多——它至少是浏览器支持的正确子集,没有引入任何应该起作用但不起作用的语法(如前面的引用字符串) 。
在 6265 中,cookie 名称仍指定为 RFC 2616token
,这意味着您可以从字母中选择加上:
!#$%&'*+-.^_`|~
在 cookie 值中,它正式禁止(由浏览器过滤的)控制字符和(不一致实现的)非 ASCII 字符。它保留了 cookie_spec 对空格、逗号和分号的禁止,此外,为了与实际实现早期 RFC 的任何可怜的白痴兼容,它还禁止反斜杠和引号,除了包裹整个值的引号(但在这种情况下,引号仍然被认为是值,而不是编码方案)。这样你就剩下了字母加上:
!#$%&'()*+-./:<=>?@[]^_`{|}~
在现实世界中,我们仍在使用原始且最差的 Netscape cookie_spec,因此使用 cookie 的代码应该准备好遇到几乎任何情况,但对于生成 cookie 的代码,建议坚持使用 RFC 6265 中的子集。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)