我看到一些网站,比如stackoverflow,使用打包的cookie,其中多个cookie被打包成一个。这是一个例子:
Set-Cookie:acct = t =& s =;域= .stackapps.com;到期=周一,2016年5月30日20:16:22 GMT;路径= /;仅Http
这只是为了保存发送多个set-cookie标头,并避免在一个set-cookie标头上发送逗号分隔的cookie?这是允许的 - 但是不建议这样做吗?
打包的cookie应该只被视为一个cookie,还是需要解压缩并作为单独的cookie发回?
答案 0 :(得分:2)
我不知道"打包的概念在哪里?#34;来了。这些只是值{/ 1}}中的值,或者至少应该符合规范。让我们浏览一下RFC,看看:
=
与
完全相同Set-Cookie: acct=t=&s=; domain=.stackapps.com; expires=...
因此,它是一个单一的cookie,应该这样对待。
答案很长,对不起。我试图将目标对准那些发现RFC中难以理解的语法规则的人。如果您认为某些语法仍然难以理解,请在评论中指出。
Set-Cookie: acct="t=&s="; domain=.stackapps.com; expires=...
标头的当前RFC为RFC6265,在4.1部分中,它具有Set-Cookie
的正式语法:
Set-Cookie
这有点简洁,但我们不需要完成所有操作。首先,我们有set-cookie-header = "Set-Cookie:" SP set-cookie-string
set-cookie-string = cookie-pair *( ";" SP cookie-av )
cookie-pair = cookie-name "=" cookie-value
cookie-name = token
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
token = <token, defined in [RFC2616], Section 2.2>
cookie-av = expires-av / max-age-av / domain-av /
path-av / secure-av / httponly-av /
extension-av
expires-av = "Expires=" sane-cookie-date
sane-cookie-date = <rfc1123-date, defined in [RFC2616], Section 3.3.1>
max-age-av = "Max-Age=" non-zero-digit *DIGIT
; In practice, both expires-av and max-age-av
; are limited to dates representable by the
; user agent.
non-zero-digit = %x31-39
; digits 1 through 9
domain-av = "Domain=" domain-value
domain-value = <subdomain>
; defined in [RFC1034], Section 3.5, as
; enhanced by [RFC1123], Section 2.1
path-av = "Path=" path-value
path-value = <any CHAR except CTLs or ";">
secure-av = "Secure"
httponly-av = "HttpOnly"
extension-av = <any CHAR except CTLs or ";">
标题和空格(Set-Cookie:
),然后是SP
,这是进一步定义的。
set-cookie-string
set-cookie-header = "Set-Cookie:" SP set-cookie-string
由set-cookie-string
(进一步定义)组成,它是我们感兴趣的语法部分,也可以是一组前缀为{{1}的任意数量的cookie-pair
和一个空间。 cookie-av
构造允许语法部分出现任意数量(包括零)。
;
*()
定义了可以在cookie中使用的元数据,但我们的证明不需要它,因此我们将放弃讨论。
另一方面set-cookie-string = cookie-pair *( ";" SP cookie-av )
是一个非常简单的构造:一个cookie-av
一个强制性 cookie-pair
符号和一个cookie-name
。
=
cookie-value
被定义为cookie-pair = cookie-name "=" cookie-value
,它将我们带到另一个RFC RFC2616。在该RFC的2.2部分中,我们找到了定义cookie-name
的基本规则。
token
token
定义:
cookie-name = token
token = <token, defined in [RFC2616], Section 2.2>
token
语法表示任意次数,但至少出现一次。要查找CTL = <any US-ASCII control character
(octets 0 - 31) and DEL (127)>
...
token = 1*<any CHAR except CTLs or separators>
separators = "(" | ")" | "<" | ">" | "@"
| "," | ";" | ":" | "\" | <">
| "/" | "[" | "]" | "?" | "="
| "{" | "}" | SP | HT
使用1*<>
并查看CTL
列,man ascii
为空格(正如我们已经看到的那样),Dec
是水平制表符(9在ascii表中。)
我们感兴趣的部分是SP
不能包含HT
字符。
返回RFC6265:
token
=
在第一个cookie-pair = cookie-name "=" cookie-value
字符处停止,第一个cookie-name
字符始终是语法中显式的=
。现在,让我们最后定义=
=
我们已经看到cookie-value
表示包含零的任何事件(注意RFC允许空cookie!)。有趣的部分整个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
可以用双引号括起来(*
是你可能猜到的双引号字符。)
但最有趣的是,cookie-value
表中的DQUOTE
符号(=
)允许作为x3D
cookie-octet
但是不允许使用空格(/ %x3C-5B / <- right there!
)和分号(x20
)。
因此,x3B
标题应解释为
Set-Cookie
将其发送回服务器的标题应为
Set-Cookie: acct=t=&s=; domain=.stackapps.com; expires=...
cookie-set-header = "Set-Cookie:" SP set-cookie-string
set-cookie-string = cookie-pair *(";" cookie-av)
cookie-pair = cookie-name "=" cookie-value
cookie-name = "acct"
cookie-value = "t=&s="
按以下方式发送违反了RFC :
Cookie: acct=t=&s=