4月阅读周·HTTP权威指南:客户端识别与cookie机制之不同站点使用不同的cookie篇
引言
HTTP(Hypertext Transfer Protocol,超文本传输协议[插图])是在万维网上进行通信时所使用的协议方案。HTTP有很多应用,但最著名的是用于Web浏览器和Web服务器之间的双工通信。
《HTTP权威指南》一书将HTTP中一些互相关联且常被误解的规则梳理清楚,并编写了一系列基于各种主题的章节介绍HTTP各方面的特性。纵观全书,对HTTP“为什么”这样做进行了详细的解释,而不仅仅停留在它是“怎么做”的。此外,这本书还介绍了很多HTTP应用程序正常工作所必需且重要的非HTTP技术。
这本书主要包括以下内容:
- 第一部分描述了Web的基础构件与HTTP的核心技术
- 第二部分重点介绍了Web系统的结构构造块:HTTP服务器、代理、缓存、网关以及机器人应用程序。
- 第三部分提供了一套用于追踪身份、增强安全性以及控制内容访问的技术和技巧。
- 第四部分涵盖HTTP报文主体和Web标准,前者包含实际内容,后者描述并处理主体内容。
- 第五部分介绍了发布和传播Web内容的技巧。
- 第六部分是一些很有用的参考附录,以及相关技术的教程。
客户端识别与cookie机制
Web服务器可能会同时与数千个不同的客户端进行对话。这些服务器通常要记录下它们在与谁交谈,而不会认为所有的请求都来自匿名的客户端。
不同站点使用不同的cookie
浏览器内部的cookie罐中可以有成百上千个cookie,但浏览器不会将每个cookie都发送给所有的站点。实际上,它们通常只向每个站点发送2~3个cookie。原因如下。
- 对所有这些cookie字节进行传输会严重降低性能。浏览器实际传输的cookie字节数要比实际的内容字节数多!
- cookie中包含的是服务器特有的名值对,所以对大部分站点来说,大多数cookie都只是无法识别的无用数据。·
- 将所有的cookie发送给所有站点会引发潜在的隐私问题,那些你并不信任的站点也会获得你只想发给其他站点的信息。
1.cookie的域属性
产生cookie的服务器可以向Set-Cookie响应首部添加一个Domain属性来控制哪些站点可以看到那个cookie。比如,下面的HTTP响应首部就是在告诉浏览器将cookie user="mary17"发送给域".airtravelbargains.com"中的所有站点:
Set-cookie: user="mary17"; domain="airtravelbargains.com"
如果用户访问的是www.airtravelbargains.com@@、specials.airtravelbargains.com或任意以.airtravelbargains.com结尾的站点,下列Cookie首部都会被发布出去:
Cookie: user="mary17"
2.cookie路径属性
cookie规范甚至允许用户将cookie与部分Web站点关联起来。可以通过Path属性来实现这一功能,在这个属性列出的URL路径前缀下所有cookie都是有效的。
例如,某个Web服务器可能是由两个组织共享的,每个组织都有独立的cookie。
因此,cookie就是由服务器贴到客户端上,由客户端维护的状态片段,只会回送给那些合适的站点。下面我们来更仔细地看看cookie的技术和标准。
cookie成分
现在使用的cookie规范有两个不同的版本:cookies版本0(有时被称为Netscape cookies)和cookies版本1(RFC 2965)。cookies版本1是对cookies版本0的扩展,应用不如后者广泛。
cookie规范版本0和版本1都不是作为HTTP/1.1规范的一部分提供的。
cookies版本0(Netscape)
最初的cookie规范是由网景公司定义的。这些“版本0”的cookie定义了Set-Cookie响应首部、cookie请求首部以及用于控制cookie的字段。版本0的cookie看起来如下所示:
Set-Cookie: name=value [; expires=date] [; path=path] [; domain=domain]
[; secure]
Cookie: name1=value1 [; name2=value2] ...
1.版本0的Set-Cookie首部Set-Cookie首部有一个强制性的cookie名和cookie值。后面跟着可选的cookie属性,中间由分号分隔。
2.版本0的Cookie首部客户端发送请求时,会将所有与域、路径和安全过滤器相匹配的未过期cookie都发送给这个站点。所有cookie都被组合到一个Cookie首部中:
Cookie: session-id=002-1145265-8016838; session-id-time=1007884800
cookies版本1(RFC 2965)
RFC 2965(以前的RFC 2109)定义了一个cookie的扩展版本。这个版本1标准引入了Set-Cookie2首部和Cookie2首部,但它也能与版本0系统进行互操作。
RFC 2965 cookie标准比原始的网景公司的标准略微复杂一些,还未得到完全的支持。RFC 2965 cookie的主要改动包括下列内容。
- 为每个cookie关联上解释性文本,对其目的进行解释。
- 允许在浏览器退出时,不考虑过期时间,将cookie强制销毁。
- 用相对秒数,而不是绝对日期来表示cookie的Max-Age。
- 通过URL端口号,而不仅仅是域和路径来控制cookie的能力。
- 通过Cookie首部回送域、端口和路径过滤器(如果有的话)。
- 为实现互操作性使用的版本号。
- 在Cookie首部从名字中区分出附加关键字的$前缀。
cookie版本1的语法如下所示:
set-cookie = "Set-Cookie2:" cookies
cookies = 1#cookie
cookie = NAME "=" VALUE *("; " set-cookie-av)
NAME = attr
VALUE = value
set-cookie-av = "Comment" "=" value
| "CommentURL" "=" <"> http_URL <">
| "Discard"
| "Domain" "=" value
| "Max-Age" "=" value
| "Path" "=" value
| "Port" [ "=" <"> portlist <"> ]
| "Secure"
| "Version" "=" 1*DIGIT
portlist = 1#portnum
portnum = 1*DIGIT
cookie = "Cookie:" cookie-version 1*(("; " | ", ") cookie-value)
cookie-value = NAME "=" VALUE ["; " path] ["; " domain] ["; " port]
cookie-version = "$Version" "=" value
NAME = attr
VALUE = value
path = "$Path" "=" value
domain = "$Domain" "=" value
port = "$Port" [ "=" <"> value <"> ]
cookie2 = "Cookie2:" cookie-version
1.版本1的Set-Cookie2首部
版本1的cookie标准比网景公司标准的可用属性要多。
2.版本1的Cookie首部
版本1的cookie会带回与传送的每个cookie相关的附加信息,用来描述每个cookie途径的过滤器。每个匹配的cookie都必须包含来自相应Set-Cookie2首部的所有Domain、Port或Path属性。
比如,假设客户端以前曾收到下列五个来自Web站点www.joes-hardware.com的Set-Cookie2响应:
Set-Cookie2: ID="29046"; Domain=".joes-hardware.com"
Set-Cookie2: color=blue
Set-Cookie2: support-pref="L2"; Domain="customer-care.joes-hardware.
com"
Set-Cookie2: Coupon="hammer027"; Version="1"; Path="/tools"
Set-Cookie2: Coupon="handvac103"; Version="1"; Path="/tools/cordless"
如果客户端对路径/tools/cordless/specials.html又发起了一次请求,就会同时发送这样一个很长的Cookie首部:
Cookie: $Version="1";
ID="29046"; $Domain=".joes-hardware.com";
color="blue";
Coupon="hammer027"; $Path="/tools";
Coupon="handvac103"; $Path="/tools/cordless"
注意,所有匹配cookie都是和它们的Set-Cookie2过滤器一同传输的,而且保留关键字都是以($)开头的。
3.版本1的Cookie2首部和版本协商
Cookie2请求首部负责在能够理解不同cookie规范版本的客户端和服务器之间进行互操作性的协商。Cookie2首部告知服务器,用户Agent代理理解新形式的cookie,并提供了所支持的cookie标准版本(将其称为Cookie-Version更合适一些):
Cookie2: $Version="1"
如果服务器理解新形式的cookie,就能够识别出Cookie2首部,并在响应首部发送Set-Cookie2(而不是Set-Cookie)。如果客户端从同一个响应中既获得了Set-Cookie首部,又获得了Set-Cookie2首部,就会忽略老的Set-Cookie首部。
如果客户端既支持版本0又支持版本1的cookie,但从服务器获得的是版本0的Set-Cookie首部,就应该带着版本0的Cookie首部发送cookie。但客户端还应该发送Cookie2: $Version=“1”来告知服务器它是可以升级的。
总结
浏览器只向服务器发送服务器产生的那些cookie。joes-hardware.com产生的cookie会被发送给joes-hardware.com,不会发送给bobs-books.com或marys-movies.com。
作者介绍
非职业「传道授业解惑」的开发者叶一一。
《趣学前端》、《CSS畅想》等系列作者。华夏美食、国漫、古风重度爱好者,刑侦、无限流小说初级玩家。
如果看完文章有所收获,欢迎点赞👍 | 收藏⭐️ | 留言📝。
- 点赞
- 收藏
- 关注作者
评论(0)