我不知道“打包”的想法是从哪里来的。这些只是值中带有= 符号的cookie,或者至少应该符合规范。让我们浏览一下 RFC,看看:
Set-Cookie: acct=t=&s=; domain=.stackapps.com; expires=...
完全一样
Set-Cookie: acct="t=&s="; domain=.stackapps.com; expires=...
因此,它是一个单一的 cookie,应该被这样对待。
答案很长,抱歉。我试图针对那些发现 RFC 中的语法规则难以理解的人。如果您认为某些语法仍然难以理解,请在评论中指出。
通过 RFC
Set-Cookie 标头的当前 RFC 是 RFC6265,在 4.1 部分它具有 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由cookie-pair(进一步定义)组成,这是我们感兴趣的语法部分,以及可选的一组任意数量的cookie-av,前缀为;和一个空格。 *() 构造允许语法部分出现任意次数(包括零次)。
set-cookie-string = cookie-pair *( ";" SP cookie-av )
cookie-av 定义了可以在 cookie 中使用但我们的证明不需要的元数据,因此我们将放弃讨论。
另一方面,cookie-pair 是一个非常简单的结构:一个cookie-name 一个强制 = 符号和一个cookie-value。
cookie-pair = cookie-name "=" cookie-value
cookie-name 被定义为 token,这将我们引向另一个 RFC,RFC2616。在该 RFC 的 2.2 部分中,我们找到了定义 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*<> 语法表示出现次数不限,但至少出现一次。要查找CTLs,请使用man ascii 并检查Dec 列,SP 是空格(正如我们已经看到的),HT 是水平制表符(ascii 表中的9)。
对我们来说有趣的部分是token 不能包含= 字符。
回到 RFC6265:
cookie-pair = cookie-name "=" cookie-value
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
我们已经看到那里的* 表示任何出现,包括零(请注意,RFC 允许空 cookie!)。整个cookie-value 有趣的部分可以用双引号括起来(DQUOTE 是您可能已经猜到的双引号字符)。
但最有趣的部分是= 符号(ascii 中的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="
并且将其发送回服务器的标头应为
Cookie: acct=t=&s=
如下发送违反了 RFC:
Cookie: acct=t&; s=