【网络】HTTP报文首部字段
目录
一. 预备知识
1.1.代理、网关和隧道
1.1.1.代理
1.1.2.网关
1.1.3.隧道
1.2.保存资源的缓存
1.2.1.缓存的有效期限
1.2.2.客户端的缓存
1.3.用单台虚拟主机实现多个域名
二. HTTP首部字段
2.1.HTTP 首部字段格式
2.2.四种 HTTP 首部字段类型
三. HTTP通用首部字段
3.1.Cache-Control
3.2.Connection
3.3.Date
3.4.Pragma
3.5.Trailer
3.6.Transfer-Encoding
3.7.Upgrade
3.8.Via
3.9.Warning
四.请求首部字段
4.1.Accept
4.2.Accept-Charset
4.3.Accept-Encoding
4.4.Accept-Language
4.5.Authorization
4.6.Expect
4.7.From
4.8.Host
4.9.If-Match
4.10.If-Modified-Since
4.11.If-None-Match
4.12.If-Range
4.13.If-Unmodified-Since
4.14.Max-Forwards
4.15.Proxy-Authorization
4.16.Range
4.17.Referer
4.18.TE
4.19.User-Agent
五. 响应首部字段
5.1.Accept-Ranges
5.2.Age
5.3.ETag
5.4.Location
5.5.Proxy-Authenticate
5.6.Retry-After
5.7.Server
5.8.Vary
5.9.WWW-Authenticate
六. 实体首部字段
6.1.Allow
6.2.Content-Encoding
6.3.Content-Language
6.4.Content-Length
6.5.Content-Location
6.6.Content-MD5
6.7.Content-Range
6.8.Content-Type
6.9.Expires
6.10.Last-Modified
七.为 Cookie 服务的首部字段
7.1.Set-Cookie
7.2.Cookie
一. 预备知识
1.1.代理、网关和隧道
HTTP 通信时,除客户端和服务器以外,还有一些用于通信数据转发 的应用程序,例如代理、网关和隧道。
它们可以配合服务器工作。
这些应用程序和服务器可以将请求转发给通信线路上的下一站服务器,并且能接收从那台服务器发送的响应再转发给客户端。
1.1.1.代理
代理是一种有转发功能的应用程序,它扮演了位于服务器和客户 端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时 也接收服务器返回的响应并转发给客户端。
代理服务器的基本行为就是接收客户端发送的请求后转发给其他服务 器。代理不改变请求 URI,会直接发送给前方持有资源的目标服务 器。 持有资源实体的服务器被称为源服务器。从源服务器返回的响应经过 代理服务器后再传给客户端。
图:每次通过代理服务器转发请求或响应时,会追加写入 Via 首部信息
在 HTTP 通信过程中,可级联多台代理服务器。请求和响应的转发会 经过数台类似锁链一样连接起来的代理服务器。转发时,需要附加 Via 首部字段以标记出经过的主机信息。
使用代理服务器的理由有:利用缓存技术(稍后讲解)减少网络带宽 的流量,组织内部针对特定网站的访问控制,以获取访问日志为主要 目的,等等。
代理有多种使用方法,按两种基准分类。一种是是否使用缓存,另一 种是是否会修改报文。
- 缓存代理
代理转发响应时,缓存代理(Caching Proxy)会预先将资源的副本 (缓存)保存在代理服务器上。 当代理再次接收到对相同资源的请求时,就可以不从源服务器那里获 取资源,而是将之前缓存的资源作为响应返回。
- 透明代理
转发请求或响应时,不对报文做任何加工的代理类型被称为透明代理 (Transparent Proxy)。反之,对报文内容进行加工的代理被称为非 透明代理。
1.1.2.网关
网关是转发其他服务器通信数据的服务器,接收从客户端发送来的请 求时,它就像自己拥有资源的源服务器一样对请求进行处理。有时客 户端可能都不会察觉,自己的通信目标是一个网关。
图:利用网关可以由 HTTP 请求转化为其他协议通信 网关的工作机制和代理十分相似。而网关能使通信线路上的服务器提 供非 HTTP 协议服务。
利用网关能提高通信的安全性,因为可以在客户端与网关之间的通信 线路上加密以确保连接的安全。
比如,网关可以连接数据库,使用 SQL 语句查询数据。另外,在 Web 购物网站上进行信用卡结算时, 网关可以和信用卡结算系统联动。
1.1.3.隧道
隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方 通信连接的应用程序。
隧道可按要求建立起一条与其他服务器的通信线路,届时使用 SSL 等 加密手段进行通信。隧道的目的是确保客户端能与服务器进行安全的 通信。 隧道本身不会去解析 HTTP 请求。也就是说,请求保持原样中转给之 后的服务器。隧道会在通信双方断开连接时结束。
图:通过隧道的传输,可以和远距离的服务器安全通信。隧道本 身是透明的,客户端不用在意隧道的存在
1.2.保存资源的缓存
缓存是指代理服务器或客户端本地磁盘内保存的资源副本。
利用缓存 可减少对源服务器的访问,因此也就节省了通信流量和通信时间。
缓存服务器是代理服务器的一种,并归类在缓存代理类型中。
换句话 说,当代理转发从服务器返回的响应时,代理服务器将会保存一份资 源的副本。
缓存服务器的优势在于利用缓存可避免多次从源服务器转发资源。
因此客户端可就近从缓存服务器上获取资源,而源服务器也不必多次处 理相同的请求了。
1.2.1.缓存的有效期限
即便缓存服务器内有缓存,也不能保证每次都会返回对同资源的请求。
因为这关系到被缓存资源的有效性问题。
当遇上源服务器上的资源更新时,如果还是使用不变的缓存,那就会 演变成返回更新前的“旧”资源了。
即使存在缓存,也会因为客户端的要求、缓存的有效期等因素,向源 服务器确认资源的有效性。
若判断缓存失效,缓存服务器将会再次从 源服务器上获取“新”资源。
1.2.2.客户端的缓存
缓存不仅可以存在于缓存服务器内,还可以存在客户端浏览器中。
以 Internet Explorer 程序为例,把客户端缓存称为临时网络文件 (Temporary Internet File)。
浏览器缓存如果有效,就不必再向服务器请求相同的资源了,可以直 接从本地磁盘内读取。
另外,和缓存服务器相同的一点是,当判定缓存过期后,会向源服务 器确认资源的有效性。
若判断浏览器缓存失效,浏览器会再次请求新 资源。
1.3.用单台虚拟主机实现多个域名
HTTP/1.1 规范允许一台 HTTP 服务器搭建多个 Web 站点。
比如,提 供 Web 托管服务(Web Hosting Service)的供应商,可以用一台服务 器为多位客户服务,也可以以每位客户持有的域名运行各自不同的网 站。
这是因为利用了虚拟主机(Virtual Host,又称虚拟服务器)的功 能。
即使物理层面只有一台服务器,但只要使用虚拟主机的功能,则可以 假想已具有多台服务器。
客户端使用 HTTP 协议访问服务器时,会经常采用类似 www.hackr.jp 这样的主机名和域名。
在互联网上,域名通过 DNS 服务映射到 IP 地址(域名解析)之后访 问目标网站。
可见,当请求发送到服务器时,已经是以 IP 地址形式 访问了。
所以,如果一台服务器内托管了 www.tricorder.jp 和 www.hackr.jp 这 两个域名,当收到请求时就需要弄清楚究竟要访问哪个域名。
在相同的 IP 地址下,由于虚拟主机可以寄存多个不同主机名和域名 的 Web 网站,因此在发送 HTTP 请求时,必须在 Host 首部内完整指 定主机名或域名的 URI。
二. HTTP首部字段
HTTP 首部字段是构成 HTTP 报文的要素之一。
在客户端与服务器之 间以 HTTP 协议进行通信的过程中,无论是请求还是响应都会使用首 部字段,它能起到传递额外重要信息的作用。
使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的 语言、认证信息等内容。
其中这个响应/请求报头里面的内容都是我们现在要讲的首部字段
2.1.HTTP 首部字段格式
HTTP 首部字段是由首部字段名和字段值构成的,中间用冒号“:” 分 隔。
首部字段名: 字段值
例如,在 HTTP 首部中以 Content-Type 这个字段来表示报文主体的 对象类型。
Content-Type: text/html
就以上述示例来看,首部字段名为 Content-Type,字符串 text/html 是 字段值。
另外,字段值对应单个 HTTP 首部字段可以有多个值,如下所示。
Keep-Alive: timeout=15, max=100
- 当 HTTP 报文首部中出现了两个或两个以上具有相同首部字段名时 会怎么样?
这种情况在规范内尚未明确,根据浏览器内部处理逻辑 的不同,结果可能并不一致。有些浏览器会优先处理第一次出现的 首部字段,而有些则会优先处理最后出现的首部字段。
2.2.四种 HTTP 首部字段类型
HTTP 首部字段根据实际用途被分为以下 4 种类型。
- 通用首部字段(General Header Fields) :请求报文和响应报文两方都会使用的首部。
- 请求首部字段(Request Header Fields) :从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加 内容、客户端信息、响应内容相关优先级等信息。
- 响应首部字段(Response Header Fields) :从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加 内容,也会要求客户端附加额外的内容信息。
- 实体首部字段(Entity Header Fields): 针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更 新时间等与实体有关的信息。
表 1:通用首部字段
首部字段名 | 说明 |
---|---|
Cache-Control | 控制缓存的行为 |
Connection | 逐跳首部、连接的管理 |
Date | 创建报文的日期时间 |
Pragma | 报文指令 |
Trailer | 报文末端的首部一览 |
Transfer-Encoding | 指定报文主体的传输编码方式 |
Upgrade | 升级为其他协议 |
Via | 代理服务器的相关信息 |
Warning | 错误通知 |
表 2:请求首部字段
首部字段名 | 说明 |
---|---|
Accept | 用户代理可处理的媒体类型 |
Accept-Charset | 优先的字符集 |
Accept-Encoding | 优先的内容编码 |
Accept-Language | 优先的语言(自然语言) |
Authorization | Web认证信息 |
Expect | 期待服务器的特定行为 |
From | 用户的电子邮箱地址 |
Host | 请求资源所在服务器 |
If-Match | 比较实体标记(ETag) |
If-Modified-Since | 比较资源的更新时间 |
If-None-Match | 比较实体标记(与 If-Match 相反) |
If-Range | 资源未更新时发送实体 Byte 的范围请求 |
If-Unmodified-Since | 比较资源的更新时间(与If-Modified-Since相反) |
Max-Forwards | 最大传输逐跳数 |
Proxy-Authorization | 代理服务器要求客户端的认证信息 |
Range | 实体的字节范围请求 |
Referer | 对请求中 URI 的原始获取方 |
TE | 传输编码的优先级 |
User-Agent | HTTP 客户端程序的信息 |
表 3:响应首部字段
首部字段名 | 说明 |
---|---|
Accept-Ranges | 是否接受字节范围请求 |
Age | 推算资源创建经过时间 |
ETag | 资源的匹配信息 |
Location | 令客户端重定向至指定URI |
Proxy-Authenticate | 代理服务器对客户端的认证信息 |
Retry-After | 对再次发起请求的时机要求 |
Server | HTTP服务器的安装信息 |
Vary | 代理服务器缓存的管理信息 |
WWW-Authenticate | 服务器对客户端的认证信息 |
表 4:实体首部字段
首部字段名 | 说明 |
---|---|
Allow | 资源可支持的HTTP方法 |
Content-Encoding | 实体主体适用的编码方式 |
Content-Language | 实体主体的自然语言 |
Content-Length | 实体主体的大小(单位:字节) |
Content-Location | 替代对应资源的URI |
Content-MD5 | 实体主体的报文摘要 |
Content-Range | 实体主体的位置范围 |
Content-Type | 实体主体的媒体类型 |
Expires | 实体主体过期的日期时间 |
Last-Modified | 资源的最后修改日期时间 |
三. HTTP通用首部字段
3.1.Cache-Control
Cache-Control 通过指定首部字段 Cache-Control 的指令,就能操作缓存的工作机制。
指令的参数是可选的,多个指令之间通过“,”分隔。首部字段 Cache Control 的指令可用于请求及响应时。
Cache-Control: private, max-age=0, no-cache
表 5:缓存请求指令
指令参数 | 说明 |
---|---|
no-cache | 无强制要求,但通常意味着在缓存响应之前,必须先向源服务器验证该响应的有效性 |
no-store | 不可缓存请求或响应的任何内容,即不存储任何缓存副本 |
max-age = [ 秒] | 必需参数,指定响应的最大 Age 值(以秒为单位),即响应在缓存中可被视为新鲜的最长时间 |
max-stale ( = [ 秒]) | 可省略参数,如果提供,则客户端愿意接收已过期的响应,且过期时间不超过指定的秒数 |
min-fresh = [ 秒] | 必需参数,客户端期望在指定的秒数时间内,响应仍然有效(未过期) |
no-transform | 代理服务器不可更改媒体类型,即保持原始响应的内容不变 |
only-if-cached | 仅从缓存中获取资源,不向源服务器发送请求 |
cache-extension- | 新指令标记(token),用于扩展 Cache-Control 首部的功能,由具体实现定义 |
表 6:缓存响应指令
指令参数 | 说明 |
---|---|
public | 响应可向任意方提供缓存,即可以被共享缓存(如代理服务器)存储和提供 |
private | 可省略参数,响应仅向特定用户返回,即仅限私有缓存(如浏览器缓存)存储和提供 |
no-cache | 可省略参数,但通常意味着在缓存响应之前,必须先向源服务器验证该响应的有效性(与请求中的 no-cache 类似,但应用于响应) |
no-store | 不可缓存请求或响应的任何内容,即不存储任何缓存副本(与请求中的 no-store 相同) |
no-transform | 代理服务器不可更改媒体类型,即保持原始响应的内容不变(与请求中的 no-transform 相同) |
must-revalidate | 缓存必须再向源服务器进行确认,以验证响应是否仍然有效,在过期后不可直接使用缓存 |
proxy-revalidate | 要求中间缓存服务器(如代理服务器)对缓存的响应有效性再次进行确认,类似于 must-revalidate 但针对中间缓存 |
max-age = [ 秒] | 必需参数,指定响应的最大 Age 值(以秒为单位),即响应在缓存中可被视为新鲜的最长时间(与请求中的 max-age 相同) |
s-maxage = [ 秒] | 必需参数(仅适用于共享缓存),指定公共缓存服务器(如代理服务器)响应的最大 Age 值,覆盖 max-age |
cache-extension- | 新指令标记(token),用于扩展 Cache-Control 首部的功能,由具体实现定义(与请求中的 cache-extension- 类似) |
- public 指令
Cache-Control: public
当指定使用 public 指令时,则明确表明其他用户也可利用缓存。
- private 指令
Cache-Control: private
当指定 private 指令后,响应只以特定的用户作为对象,这与 public 指令的行为相反。
缓存服务器会对该特定用户提供资源缓存的服务,对于其他用户发送 过来的请求,代理服务器则不会返回缓存。
- no-cache 指令
Cache-Control: no-cache
使用 no-cache 指令的目的是为了防止从缓存中返回过期的资源。
- 如果客户端发送的请求中如果包含 no-cache 指令,则表示客户端将不会接收缓存过的响应。于是,“中间”的缓存服务器必须把客户端请求转发给源服务器。
- 如果服务器返回的响应中包含 no-cache 指令,那么缓存服务器不能对资源进行缓存。源服务器以后也将不再对缓存服务器请求中提出的资 源有效性进行确认,且禁止其对响应资源进行缓存操作。
Cache-Control: no-cache=Location
由服务器返回的响应中,若报文首部字段 Cache-Control 中对 no-cache 字段名具体指定参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存。
换言之,无参数值的首部字段可以使用缓存。只能在响应指令中指定该参数。
- no-store 指令
Cache-Control: no-store
当使用 no-store 指令时,暗示请求(和对应的响应)或响应中包含 机密信息。
因此,该指令规定缓存不能在本地存储请求或响应的任一部分。
从字面意思上很容易把 no-cache 误解成为不缓存,但事实上 no-cache 代表不缓存过期的资源,缓存会向源服务器进行有效期确认后处理资源,也许称为 do-not serve-from-cache-without-revalidation 更合适。
no-store 才是真正地不进行缓存,请读者注意区别理解。
- max-age 指令
Cache-Control: max-age=604800(单位:秒)
当客户端发送的请求中包含 max-age 指令时,如果判定缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源。 另外,当指定 max-age 值为 0,那么缓存服务器通常需要将请求转发给源服务器。
当服务器返回的响应中包含 max-age 指令时,缓存服务器将不对资源的有效性再作确认,而 max-age 数值代表资源保存为缓存的最长时间。
应用 HTTP/1.1 版本的缓存服务器遇到同时存在 Expires 首部字段的情 况时,会优先处理 max-age 指令,而忽略掉 Expires 首部字段。
而 HTTP/1.0 版本的缓存服务器的情况却相反,max-age 指令会被忽略 掉。
- s-maxage 指令
Cache-Control: s-maxage=604800(单位 :秒)
s-maxage 指令的功能和 max-age 指令的相同,它们的不同点是 s-maxage 指令只适用于供多位用户使用的公共缓存服务器 。
也就是说,对于向同一用户重复返回响应的服务器来说,这个指令没有任何 作用。
这里的公共缓存服务器一般指代理。
另外,当使用 s-maxage 指令后,则直接忽略对 Expires 首部字段及 max-age 指令的处理
- min-fresh 指令
Cache-Control: min-fresh=60(单位:秒)
min-fresh 指令要求缓存服务器返回至少还未过指定时间的缓存资源。
比如,当指定 min-fresh 为 60 秒后,过了 60 秒的资源都无法作为响 应返回了。
- max-stale 指令
Cache-Control: max-stale=3600(单位:秒)
使用 max-stale 可指示缓存资源,即使过期也照常接收。
如果指令未指定参数值,那么无论经过多久,客户端都会接收响应;
如果指令中指定了具体数值,那么即使过期,只要仍处于 max-stale 指定的时间内,仍旧会被客户端接收。
- only-if-cached 指令
Cache-Control: only-if-cached
使用 only-if-cached 指令表示客户端仅在缓存服务器本地缓存目标资 源的情况下才会要求其返回。
换言之,该指令要求缓存服务器不重新加载响应,也不会再次确认资源有效性。
若发生请求缓存服务器的本地缓存无响应,则返回状态码 504 Gateway Timeout。
- must-revalidate 指令
Cache-Control: must-revalidate
使用 must-revalidate 指令,代理会向源服务器再次验证即将返回的响 应缓存目前是否仍然有效。 若代理无法连通源服务器再次获取有效资源的话,缓存必须给客户端 一条 504(Gateway Timeout)状态码。
另外,使用 must-revalidate 指令会忽略请求的 max-stale 指令(即使已 经在首部使用了 max-stale,也不会再有效果)。
- proxy-revalidate 指令
Cache-Control: proxy-revalidate
proxy-revalidate 指令要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性。
- no-transform 指令
Cache-Control: no-transform
使用 no-transform 指令规定无论是在请求还是响应中,缓存都不能改 变实体主体的媒体类型。 这样做可防止缓存或代理压缩图片等类似操作。
3.2.Connection
Connection 首部字段具备如下两个作用。
- 控制不再转发给代理的首部字段
- 管理持久连接
- 控制不再转发给代理的首部字段
Connection: 不再转发的首部字段名
在客户端发送请求和服务器返回响应内,使用 Connection 首部字 段,可控制不再转发给代理的首部字段(即 Hop-by-hop 首 部)。
- 管理持久连接
Connection: close
HTTP/1.1 版本的默认连接都是持久连接。
为此,客户端会在持久连接上连续发送请求。
当服务器端想明确断开连接时,则指定 Connection 首部字段的值为 Close。
Connection: Keep-Alive
HTTP/1.1 之前的 HTTP 版本的默认连接都是非持久连接。
为此,如果想在旧版本的 HTTP 协议上维持持续连接,则需要指定 Connection 首部字段的值为 Keep-Alive。
如上图所示,客户端发送请求给服务器时,服务器端会像上图那样加上首部字段 Keep-Alive 及首部字段 Connection 后返回 响应。
3.3.Date
首部字段 Date 表明创建 HTTP 报文的日期和时间。
HTTP/1.1 协议使用在 RFC1123 中规定的日期时间的格式,如下示例。
Date: Tue, 03 Jul 2012 04:40:59 GMT
之前的 HTTP 协议版本中使用在 RFC850 中定义的格式,如下所示。
Date: Tue, 03-Jul-12 04:40:59 GMT
除此之外,还有一种格式。它与 C 标准库内的 asctime() 函数的输出 格式一致。
Date: Tue Jul 03 04:40:59 2012
3.4.Pragma
Pragma 是 HTTP/1.1 之前版本的历史遗留字段,仅作为与 HTTP/1.0 的向后兼容而定义。 规范定义的形式唯一,如下所示。
Pragma: no-cache
该首部字段属于通用首部字段,但只用在客户端发送的请求中。客户 端会要求所有的中间服务器不返回缓存的资源。
所有的中间服务器如果都能以 HTTP/1.1 为基准,那直接采用 Cache Control: no-cache 指定缓存的处理方式是最为理想的。
但要整体掌握 全部中间服务器使用的 HTTP 协议版本却是不现实的。
因此,发送的 请求会同时含有下面两个首部字段。
Cache-Control: no-cache
Pragma: no-cache
3.5.Trailer
首部字段 Trailer 会事先说明在报文主体后记录了哪些首部字段。
该 首部字段可应用在 HTTP/1.1 版本分块传输编码时。
以上用例中,指定首部字段 Trailer 的值为 Expires,在报文主体之后 (分块长度 0 之后)出现了首部字段 Expires。
3.6.Transfer-Encoding
首部字段 Transfer-Encoding 规定了传输报文主体时采用的编码方式。
HTTP/1.1 的传输编码方式仅对分块传输编码有效。
以上用例中,正如在首部字段 Transfer-Encoding 中指定的那样,有效 使用分块传输编码,且分别被分成 3312 字节和 914 字节大小的分块 数据。
3.7.Upgrade
首部字段 Upgrade 用于检测 HTTP 协议及其他协议是否可使用更高的 版本进行通信,其参数值可以用来指定一个完全不同的通信协议。
上图用例中,首部字段 Upgrade 指定的值为 TLS/1.0。请注意此处两 个字段首部字段的对应关系,Connection 的值被指定为 Upgrade。 Upgrade 首部字段产生作用的 Upgrade 对象仅限于客户端和邻接服务 器之间。
因此,使用首部字段 Upgrade 时,还需要额外指定 Connection:Upgrade。
对于附有首部字段 Upgrade 的请求,服务器可用 101 Switching Protocols 状态码作为响应返回
3.8.Via
使用首部字段 Via 是为了追踪客户端与服务器之间的请求和响应报文 的传输路径。
报文经过代理或网关时,会先在首部字段 Via 中附加该服务器的信 息,然后再进行转发。
这个做法和 traceroute 及电子邮件的 Received 首部的工作机制很类似。
首部字段 Via 不仅用于追踪报文的转发,还可避免请求回环的发生。
所以必须在经过代理时附加该首部字段内容。
上图用例中,在经过代理服务器 A 时,Via 首部附加了“1.0 gw.hackr.jp (Squid/3.1)”这样的字符串值。
行头的 1.0 是指接收请求的 97 服务器上应用的 HTTP 协议版本。
接下来经过代理服务器 B 时亦是如 此,在 Via 首部附加服务器信息,也可增加 1 个新的 Via 首部写入服 务器信息。
Via 首部是为了追踪传输路径,所以经常会和 TRACE 方法一起使 用。
比如,代理服务器接收到由 TRACE 方法发送过来的请求(其中 Max-Forwards: 0)时,代理服务器就不能再转发该请求了。这种情况 下,代理服务器会将自身的信息附加到 Via 首部后,返回该请求的响 应。
3.9.Warning
HTTP/1.1 的 Warning 首部是从 HTTP/1.0 的响应首部(Retry-After)演 变过来的。
该首部通常会告知用户一些与缓存相关的问题的警告。
Warning: 113 gw.hackr.jp:8080 "Heuristic expiration" Tue, 03 Jul 2012
Warning 首部的格式如下。
Warning: [警告码][警告的主机:端口号]“[警告内容]”([日期时间])
最后的日期时间部分可省略。
HTTP/1.1 中定义了 7 种警告。警告码对应的警告内容仅推荐参考。 另外,警告码具备扩展性,今后有可能追加新的警告码。
HTTP/1.1 警告码
警告码 | 警告内容 | 说明 |
---|---|---|
110 | Response is stale(响应已过期) | 代理返回已过期的资源 |
111 | Revalidation failed(再验证失败) | 代理再验证资源有效性时失败(服务器无法到达等原因) |
112 | Disconnection operation(断开连接操作) | 代理与互联网连接被故意切断 |
113 | Heuristic expiration(试探性过期) | 响应的使用期超过24小时(有效缓存的设定时间大于24小时的情况下) |
199 | Miscellaneous warning(杂项警告) | 任意的警告内容 |
214 | Transformation applied(使用了转换) | 代理对内容编码或媒体类型等执行了某些处理时 |
299 | Miscellaneous persistent warning(持久杂项警告) | 任意的警告内容 |
四.请求首部字段
请求首部字段是从客户端往服务器端发送请求报文中所使用的字段, 用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等 内容。
4.1.Accept
Accept 首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。
可使用 type/subtype 这种形式,一次指定多种媒 体类型。
下面我们试举几个媒体类型的例子。
- 文本文件 :text/html, text/plain, text/css ... ,application/xhtml+xml, application/xml ...
- 图片文件 :image/jpeg, image/gif, image/png ...
- 视频文件 :video/mpeg, video/quicktime ...
- 应用程序使用的二进制文件 :application/octet-stream, application/zip ...
比如,如果浏览器不支持 PNG 图片的显示,那 Accept 就不指定 image/png,而指定可处理的 image/gif 和 image/jpeg 等图片类型。
若想要给显示的媒体类型增加优先级,则使用 q= 来额外表示权重值 1,用分号(;)进行分隔。权重值 q 的范围是 0~1(可精确到小数点 后 3 位),且 1 为最大值。不指定权重 q 值时,默认权重为 q=1.0。
当服务器提供多种内容时,将会首先返回权重值最高的媒体类型。
我们看个例子
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.
text/html
:- 客户端希望优先接收
text/html
格式的内容。 - 由于没有指定
q
参数,默认优先级为 1.0,表示最高优先级。
- 客户端希望优先接收
application/xhtml+xml
:- 客户端可以接受
application/xhtml+xml
格式的内容。 - 同样,默认优先级为 1.0。
- 客户端可以接受
application/xml;q=0.9
:- 客户端可以接受
application/xml
格式的内容,但优先级为 0.9,比text/html
和application/xhtml+xml
低。
- 客户端可以接受
*/*;q=0.8
:- 客户端可以接受任何其他类型的内容(
*/*
表示通配符),优先级为 0.8,是最低的优先级。
- 客户端可以接受任何其他类型的内容(
4.2.Accept-Charset
Accept-Charset 首部字段可用来通知服务器,用户代理支持的字符集及字符集的相对优先顺序。
另外,可一次性指定多种字符集。与首部字 段 Accept 相同的是可用权重 q 值来表示相对优先级。 该首部字段应用于内容协商机制的服务器驱动协商。
看个例子
Accept-Charset: iso-8859-5, unicode-1-1;q=0.8
iso-8859-5
:- 客户端希望优先接收
iso-8859-5
字符集编码的内容。 - 由于没有指定
q
参数,默认优先级为 1.0,表示最高优先级。
- 客户端希望优先接收
unicode-1-1;q=0.8
:- 客户端可以接受
unicode-1-1
字符集编码的内容,但优先级为 0.8,比iso-8859-5
低。
- 客户端可以接受
4.3.Accept-Encoding
首部字段用来告知服务器用户代理支持的内容编码及 内容编码的优先级顺序。
可一次性指定多种内容编码。
下面试举出几个内容编码的例子。
- gzip:由文件压缩程序 gzip(GNU zip)生成的编码格式 (RFC1952),采用 Lempel-Ziv 算法(LZ77)及 32 位循环冗余 校验(Cyclic Redundancy Check,通称 CRC)。
- compress:由 UNIX 文件压缩程序 compress 生成的编码格式,采用 Lempel Ziv-Welch 算法(LZW)。
- deflate:组合使用 zlib 格式(RFC1950)及由 deflate 压缩算法 (RFC1951)生成的编码格式。 identity 不执行压缩或不会变化的默认编码格式
采用权重 q 值来表示相对优先级,这点与首部字段 Accept 相同。另 外,也可使用星号(*)作为通配符,指定任意的编码格式。
看个例子
Accept-Encoding: gzip, deflate Accept-Encoding
4.4.Accept-Language
首部字段 Accept-Language 用来告知服务器用户代理能够处理的自然 语言集(指中文或英文等),以及自然语言集的相对优先级。
可一次 指定多种自然语言集。
和 Accept 首部字段一样,按权重值 q 来表示相对优先级。
看个例子
Accept-Language: zh-cn,zh;q=0.7,en-us,en;q=0.3
zh-cn
:- 客户端希望优先接收简体中文(
zh-cn
,表示中文,地区为中国)的内容。 - 由于没有指定
q
参数,默认优先级为 1.0,表示最高优先级。
- 客户端希望优先接收简体中文(
zh;q=0.7
:- 客户端可以接受中文(不指定地区,
zh
)的内容,但优先级为 0.7,比zh-cn
低。 - 这意味着如果服务器没有
zh-cn
版本的内容,但有zh
版本的内容,客户端也可以接受。
- 客户端可以接受中文(不指定地区,
en-us
:- 客户端可以接受美式英语(
en-us
)的内容。 - 默认优先级为 1.0(如果仅从这一条看,但实际优先级受其他条目影响,因为
zh-cn
优先级更高)。不过,由于它出现在zh
之后且没有显式指定比zh
更低的q
值,其实际优先级在zh
之后但高于en
。但在此上下文中,其直接优先级仅次于zh-cn
(因为zh
已经有一个明确的较低优先级)。
- 客户端可以接受美式英语(
en;q=0.3
:- 客户端可以接受英语(不指定地区,
en
)的内容,但优先级为 0.3,是最低的优先级。 - 这意味着如果服务器没有
zh-cn
、zh
或en-us
版本的内容,但有en
版本的内容,客户端也可以接受,但这不是首选。
- 客户端可以接受英语(不指定地区,
在上述图 例中,客户端在服务器有中文版资源的情况下,会请求其返回中文版 对应的响应,没有中文版时,则请求返回英文版响应。
4.5.Authorization
Authorization: Basic dWVub3NlbjpwYXNzd29yZA==
首部字段 Authorization 是用来告知服务器,用户代理的认证信息(证 书值)。
通常,想要通过服务器认证的用户代理会在接收到返回的 401 状态码响应后,把首部字段 Authorization 加入请求中。
共用缓存 在接收到含有 Authorization 首部字段的请求时的操作处理会略有差 异。
4.6.Expect
Expect: 100-continue
客户端使用首部字段 Expect 来告知服务器,期望出现的某种特定行为。
因服务器无法理解客户端的期望作出回应而发生错误时,会返回状态码 417 Expectation Failed。 客户端可以利用该首部字段,写明所期望的扩展。
虽然 HTTP/1.1 规 范只定义了 100-continue(状态码 100 Continue 之意)。
等待状态码 100 响应的客户端在发生请求时,需要指定 Expect:100 continue。
4.7.From
首部字段 From 用来告知服务器使用用户代理的用户的电子邮件地址。
通常,其使用目的就是为了显示搜索引擎等用户代理的负责人的 电子邮件联系方式。
使用代理时,应尽可能包含 From 首部字段(但 可能会因代理不同,将电子邮件地址记录在 User-Agent 首部字段 内)
4.8.Host
图:虚拟主机运行在同一个 IP 上,因此使用首部字段 Host 加以 区分
Host: www.hackr.jp
首部字段 Host 会告知服务器,请求的资源所处的互联网主机名和端 口号。
Host 首部字段在 HTTP/1.1 规范内是唯一一个必须被包含在请 求内的首部字段。
首部字段 Host 和以单台服务器分配多个域名的虚拟主机的工作机制 有很密切的关联,这是首部字段 Host 必须存在的意义。
请求被发送至服务器时,请求中的主机名会用 IP 地址直接替换解 决。
但如果这时,相同的 IP 地址下部署运行着多个域名,那么服务 器就会无法理解究竟是哪个域名对应的请求。
因此,就需要使用首部 字段 Host 来明确指出请求的主机名。
若服务器未设定主机名,那直 接发送一个空值即可。如下所示。
Host:
4.9.If-Match
图:附带条件请求 形如 If-xxx 这种样式的请求首部字段,都可称为条件请求。
服务器接 收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
图:只有当 If-Match 的字段值跟 ETag 值匹配一致时,服务器才会 接受请求
If-Match: "123456"
首部字段 If-Match,属附带条件之一,它会告知服务器匹配资源所用 的实体标记(ETag)值。
这时的服务器无法使用弱 ETag 值。
服务器会比对 If-Match 的字段值和资源的 ETag 值,仅当两者一致 时,才会执行请求。
反之,则返回状态码 412 Precondition Failed 的响 应。
还可以使用星号(*)指定 If-Match 的字段值。
针对这种情况,服务 器将会忽略 ETag 的值,只要资源存在就处理请求。
4.10.If-Modified-Since
图:如果在 If-Modified-Since 字段指定的日期时间后,资源发生了 更新,服务器会接受请求
If-Modified-Since: Thu, 15 Apr 2004 00:00:00 GMT
首部字段 If-Modified-Since,属附带条件之一,它会告知服务器若 If Modified-Since 字段值早于资源的更新时间,则希望能处理该请求。
而在指定 If-Modified-Since 字段值的日期时间之后,如果请求的资源 都没有过更新,则返回状态码 304 Not Modified 的响应。
If-Modified-Since 用于确认代理或客户端拥有的本地资源的有效性。 获取资源的更新日期时间,可通过确认首部字段 Last-Modified 来确 定。
4.11.If-None-Match
图:只有在 If-None-Match 的字段值与 ETag 值不一致时,可处理 该请求。
与 If-Match 首部字段的作用相反 首部字段 If-None-Match 属于附带条件之一。
它和首部字段 If-Match 作用相反。
用于指定 If-None-Match 字段值的实体标记(ETag)值与 请求资源的 ETag 不一致时,它就告知服务器处理该请求。
在 GET 或 HEAD 方法中使用首部字段 If-None-Match 可获取最新的资 源。
因此,这与使用首部字段 If-Modified-Since 时有些类似。
4.12.If-Range
首部字段 If-Range 属于附带条件之一。
它告知服务器若指定的 If Range 字段值(ETag 值或者时间)和请求资源的 ETag 值或时间相一 致时,则作为范围请求处理。
反之,则返回全体资源。
下面我们思考一下不使用首部字段 If-Range 发送请求的情况。
服务器 端的资源如果更新,那客户端持有资源中的一部分也会随之无效,当 然,范围请求作为前提是无效的。
这时,服务器会暂且以状态码 412 Precondition Failed 作为响应返回,其目的是催促客户端再次发送请 求。
这样一来,与使用首部字段 If-Range 比起来,就需要花费两倍的 功夫。
4.13.If-Unmodified-Since
If-Unmodified-Since: Thu, 03 Jul 2012 00:00:00 GMT
首部字段 If-Unmodified-Since 和首部字段 If-Modified-Since 的作用相 反。
它的作用的是告知服务器,指定的请求资源只有在字段值内指定 的日期时间之后,未发生更新的情况下,才能处理请求。
如果在指定 日期时间后发生了更新,则以状态码 412 Precondition Failed 作为响应 返回。
4.14.Max-Forwards
图:每次转发数值减 1。当数值变 0 时返回响应
Max-Forwards: 10
通过 TRACE 方法或 OPTIONS 方法,发送包含首部字段 Max Forwards 的请求时,该字段以十进制整数形式指定可经过的服务器最大数目。
服务器在往下一个服务器转发请求之前,Max-Forwards 的 值减 1 后重新赋值。
当服务器接收到 Max-Forwards 值为 0 的请求 时,则不再进行转发,而是直接返回响应。
使用 HTTP 协议通信时,请求可能会经过代理等多台服务器。途中, 如果代理服务器由于某些原因导致请求转发失败,客户端也就等不到 服务器返回的响应了。对此,我们无从可知。
可以灵活使用首部字段 Max-Forwards,针对以上问题产生的原因展 开调查。
由于当 Max-Forwards 字段值为 0 时,服务器就会立即返回 响应,由此我们至少可以对以那台服务器为终点的传输路径的通信状 况有所把握。
4.15.Proxy-Authorization
Proxy-Authorization: Basic dGlwOjkpNLAGfFY5
接收到从代理服务器发来的认证质询时,客户端会发送包含首部字段 Proxy-Authorization 的请求,以告知服务器认证所需要的信息。
这个行为是与客户端和服务器之间的 HTTP 访问认证相类似的,不同 之处在于,认证行为发生在客户端与代理之间。
客户端与服务器之间 的认证,使用首部字段 Authorization 可起到相同作用。
有关 HTTP 访 问认证,后面的章节会作详尽阐述。
4.16.Range
Range: bytes=5001-10000
对于只需获取部分资源的范围请求,包含首部字段 Range 即可告知服 务器资源的指定范围。
上面的示例表示请求获取从第 5001 字节至第 10000 字节的资源。
接收到附带 Range 首部字段请求的服务器,会在处理请求之后返回状 态码为 206 Partial Content 的响应。
无法处理该范围请求时,则会返 回状态码 200 OK 的响应及全部资源。
4.17.Referer
Referer: http://www.hackr.jp/index.htm
首部字段 Referer 会告知服务器请求的原始资源的 URI。
客户端一般都会发送 Referer 首部字段给服务器。但当直接在浏览器 的地址栏输入 URI,或出于安全性的考虑时,也可以不发送该首部字 段。
因为原始资源的 URI 中的查询字符串可能含有 ID 和密码等保密信 息,要是写进 Referer 转发给其他服务器,则有可能导致保密信息的 泄露。
另外,Referer 的正确的拼写应该是 Referrer,但不知为何,大家一直 沿用这个错误的拼写。
4.18.TE
TE: gzip, deflate;q=0.5
首部字段 TE 会告知服务器客户端能够处理响应的传输编码方式及相 对优先级。
它和首部字段 Accept-Encoding 的功能很相像,但是用于 传输编码。
首部字段 TE 除指定传输编码之外,还可以指定伴随 trailer 字段的分 块传输编码的方式。
应用后者时,只需把 trailers 赋值给该字段值。
TE: trailers
4.19.User-Agent
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/2010010
首部字段 User-Agent 会将创建请求的浏览器和用户代理名称等信息传达给服务器。
由网络爬虫发起请求时,有可能会在字段内添加爬虫作者的电子邮件 地址。
此外,如果请求经过代理,那么中间也很可能被添加上代理服务器的名称。
五. 响应首部字段
响应首部字段是由服务器端向客户端返回响应报文中所使用的字段, 用于补充响应的附加信息、服务器信息,以及对客户端的附加要求等 信息.
5.1.Accept-Ranges
图:当不能处理范围请求时,Accept-Ranges: none
Accept-Ranges: bytes
首部字段 Accept-Ranges 是用来告知客户端服务器是否能处理范围请 求,以指定获取服务器端某个部分的资源。
可指定的字段值有两种,可处理范围请求时指定其为 bytes,反之则 指定其为 none。
5.2.Age
Age: 600
首部字段 Age 能告知客户端,源服务器在多久前创建了响应。
字段值 的单位为秒。 若创建该响应的服务器是缓存服务器,Age 值是指缓存后的响应再次 发起认证到认证完成的时间值。
代理创建响应时必须加上首部字段 Age。
5.3.ETag
ETag: "82e22293907ce725faf67773957acd12"
首部字段 ETag 能告知客户端实体标识。
它是一种可将资源以字符串 形式做唯一性标识的方式。
服务器会为每份资源分配对应的 ETag 值。
另外,当资源更新时,ETag 值也需要更新。
生成 ETag 值时,并没有 统一的算法规则,而仅仅是由服务器来分配。
另外,当资源更新时,ETag 值也需要更新。
生成 ETag 值时,并没有 统一的算法规则,而仅仅是由服务器来分配。
资源被缓存时,就会被分配唯一性标识。
例如,当使用中文版的浏览 器访问 http://www.google.com/ 时,就会返回中文版对应的资源,而 使用英文版的浏览器访问时,则会返回英文版对应的资源。
两者的 URI 是相同的,所以仅凭 URI 指定缓存的资源是相当困难的。
若在下 载过程中出现连接中断、再连接的情况,都会依照 ETag 值来指定资 源。
- 强 ETag 值和弱 Tag 值
ETag 中有强 ETag 值和弱 ETag 值之分。
强 ETag 值 : ETag 值,不论实体发生多么细微的变化都会改变其值。
ETag: "usagi-1234"
弱 ETag 值 :弱 ETag 值只用于提示资源是否相同。只有资源发生了根本改变,产 生差异时才会改变 ETag 值。这时,会在字段值最开始处附加 W/。
ETag: W/"usagi-1234"
5.4.Location
Location: http://www.usagidesign.jp/sample.html
使用首部字段 Location 可以将响应接收方引导至某个与请求 URI 位置 不同的资源。
基本上,该字段会配合 3xx :Redirection 的响应,提供重定向的 URI。
几乎所有的浏览器在接收到包含首部字段 Location 的响应后,都会强 制性地尝试对已提示的重定向资源的访问。
5.5.Proxy-Authenticate
Proxy-Authenticate: Basic realm="Usagidesign Auth"
首部字段 Proxy-Authenticate 会把由代理服务器所要求的认证信息发送 给客户端。
它与客户端和服务器之间的 HTTP 访问认证的行为相似,不同之处在 于其认证行为是在客户端与代理之间进行的。
而客户端与服务器之间 进行认证时,首部字段 WWW-Authorization 有着相同的作用。
5.6.Retry-After
Retry-After: 120
首部字段 Retry-After 告知客户端应该在多久之后再次发送请求。
主要 配合状态码 503 Service Unavailable 响应,或 3xx Redirect 响应一起使用。
字段值可以指定为具体的日期时间(Wed, 04 Jul 2012 06:34:24 GMT 等格式),也可以是创建响应后的秒数。
5.7.Server
Server: Apache/2.2.17 (Unix)
首部字段 Server 告知客户端当前服务器上安装的 HTTP 服务器应用程 序的信息。
不单单会标出服务器上的软件应用名称,还有可能包括版 本号和安装时启用的可选项。
Server: Apache/2.2.6 (Unix) PHP/5.2.5 6.5.8
5.8.Vary
图:当代理服务器接收到带有 Vary 首部字段指定获取资源的请求 时,如果使用的 Accept-Language 字段的值相同,那么就直接从缓 存返回响应。
反之,则需要先从源服务器端获取资源后才能作为响应返回
Vary: Accept-Language
首部字段 Vary 可对缓存进行控制。
源服务器会向代理服务器传达关于本地缓存使用方法的命令。
从代理服务器接收到源服务器返回包含 Vary 指定项的响应之后,若 再要进行缓存,仅对请求中含有相同 Vary 指定首部字段的请求返回 缓存。
即使对相同资源发起请求,但由于 Vary 指定的首部字段不相同,因此必须要从源服务器重新获取资源。
5.9.WWW-Authenticate
WWW-Authenticate: Basic realm="Usagidesign Auth"
首部字段 WWW-Authenticate 用于 HTTP 访问认证。
它会告知客户端 适用于访问请求 URI 所指定资源的认证方案(Basic 或是 Digest)和 带参数提示的质询(challenge)。
状态码 401 Unauthorized 响应中, 肯定带有首部字段 WWW-Authenticate。
上述示例中,realm 字段的字符串是为了辨别请求 URI 指定资源所受 到的保护策略。
六. 实体首部字段
实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首 部,用于补充内容的更新时间等与实体相关的信息。
图:在请求和响应两方的 HTTP 报文中都含有与实体相关的首部字段
6.1.Allow
Allow: GET, HEAD
首部字段 Allow 用于通知客户端能够支持 Request-URI 指定资源的所有 HTTP 方法。
当服务器接收到不支持的 HTTP 方法时,会以状态码 405 Method Not Allowed 作为响应返回。
与此同时,还会把所有能支 持的 HTTP 方法写入首部字段 Allow 后返回。
6.2.Content-Encoding
Content-Encoding: gzip
首部字段 Content-Encoding 会告知客户端服务器对实体的主体部分选 用的内容编码方式。
内容编码是指在不丢失实体信息的前提下所进行 的压缩。
主要采用以下 4 种内容编码的方式。(各方式的说明请参考 Accept-Encoding 首部字段)。
- gzip
- compress
- deflate
- identity
6.3.Content-Language
Content-Language: zh-CN
首部字段 Content-Language 会告知客户端,实体主体使用的自然语言 (指中文或英文等语言)。
6.4.Content-Length
Content-Length: 15000
首部字段 Content-Length 表明了实体主体部分的大小(单位是字 节)。
对实体主体进行内容编码传输时,不能再使用 Content-Length 首部字段。
6.5.Content-Location
Content-Location: http://www.hackr.jp/index-ja.html
首部字段 Content-Location 给出与报文主体部分相对应的 URI。
和首 部字段 Location 不同,Content-Location 表示的是报文主体返回资源对 应的 URI。
比如,对于使用首部字段 Accept-Language 的服务器驱动型请求,当 返回的页面内容与实际请求的对象不同时,首部字段 Content-Location 内会写明 URI。
(访问 http://www.hackr.jp/ 返回的对象却是 http://www.hackr.jp/index-ja.html 等类似情况)
6.6.Content-MD5
Content-MD5: OGFkZDUwNGVhNGY3N2MxMDIwZmQ4NTBmY2IyTY==
首部字段 Content-MD5 是一串由 MD5 算法生成的值,其目的在于检 查报文主体在传输过程中是否保持完整,以及确认传输到达。
对报文主体执行 MD5 算法获得的 128 位二进制数,再通过 Base64 编 码后将结果写入 Content-MD5 字段值。
由于 HTTP 首部无法记录二进 制值,所以要通过 Base64 编码处理。
为确保报文的有效性,作为接 收方的客户端会对报文主体再执行一次相同的 MD5 算法。
计算出的 值与字段值作比较后,即可判断出报文主体的准确性。
采用这种方法,对内容上的偶发性改变是无从查证的,也无法检测出 恶意篡改。
其中一个原因在于,内容如果能够被篡改,那么同时意味 着 Content-MD5 也可重新计算然后被篡改。
所以处在接收阶段的客户 端是无法意识到报文主体以及首部字段 Content-MD5 是已经被篡改过 的。
6.7.Content-Range
针对范围请求,返回响应时使用的首部字段 Content-Range,能告知客 户端作为响应返回的实体的哪个部分符合范围请求。
字段值以字节为 单位,表示当前发送部分及整个实体大小。
Content-Range: bytes 5001-10000/10000
bytes 5001-10000
- 表示当前响应中返回的数据是资源的 第 5001 字节到第 10000 字节(闭区间)。
- 字节范围从
0
开始计数,因此实际包含的是第 5002 到第 10001 个字节(如果从 1 开始计数)。
/10000
- 表示资源的总大小为 10000 字节。
6.8.Content-Type
Content-Type: text/html; charset=UTF-8
首部字段 Content-Type 说明了实体主体内对象的媒体类型。
和首部字 段 Accept 一样,字段值用 type/subtype 形式赋值
6.9.Expires
Expires
用于指示资源的过期时间
Expires: Wed, 04 Jul 2012 08:26:05 GMT
Expires
头的作用- 服务器通过该字段告诉客户端(如浏览器),资源在指定的时间之前是有效的,可以直接从缓存中读取,无需重新向服务器请求。
- 超过该时间后,客户端会认为资源已过期,需要重新向服务器验证或获取最新版本。
Wed, 04 Jul 2012 08:26:05 GMT
- 这是资源的过期时间,采用格林尼治标准时间(GMT)格式。
- 示例中表示资源在 2012 年 7 月 4 日 08:26:05(GMT 时间) 之前是有效的。
首部字段 Expires 会将资源失效的日期告知客户端。
缓存服务器在接 收到含有首部字段 Expires 的响应后,会以缓存来应答请求,在 Expires 字段值指定的时间之前,响应的副本会一直被保存。
当超过 指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求 资源。
源服务器不希望缓存服务器对资源缓存时,最好在 Expires 字段内写 入与首部字段 Date 相同的时间值。
但是,当首部字段 Cache-Control 有指定 max-age 指令时,比起首部字 段 Expires,会优先处理 max-age 指令。
6.10.Last-Modified
Last-Modified: Wed, 23 May 2012 09:59:55 GMT
首部字段 Last-Modified 指明资源最终修改的时间。
一般来说,这个 值就是 Request-URI 指定资源被修改的时间。
但类似使用 CGI 脚本进 行动态数据处理时,该值有可能会变成数据最终修改时的时间。
七.为 Cookie 服务的首部字段
首部字段名 | 说明 | 首部类型 |
---|---|---|
Set-Cookie | 服务器用于开始状态管理,向客户端发送 Cookie 信息。 | 响应首部字段 |
Cookie | 客户端在请求中携带的、之前从服务器接收到的 Cookie 信息,供服务器识别用户。 | 请求首部字段 |
7.1.Set-Cookie
服务器通过 Set-Cookie
响应头向客户端发送 Cookie 数据,客户端会保存这些数据并在后续请求中携带。
Set-Cookie: status=enable; expires=Tue, 05 Jul 2011 07:26:31 GMT; path
当服务器准备开始管理客户端的状态时,会事先告知各种信息。
属性名 | 说明 | 示例 |
---|---|---|
NAME=VALUE | 赋予 Cookie 的名称和其值(必需项)。 | sessionId=abc123 |
expires=DATE | 指定 Cookie 的有效期(UTC 格式日期)。若未指定,则 Cookie 在浏览器关闭时失效。 | expires=Wed, 04 Jul 2025 12:00:00 GMT |
path=PATH | 指定服务器上哪些目录下的页面可以访问该 Cookie。若未指定,则默认为当前文档所在目录。 | path=/ (所有路径) |
domain=域名 | 指定 Cookie 适用的域名。若未指定,则默认为创建 Cookie 的服务器的域名。 | domain=example.com |
Secure | 仅在 HTTPS 安全通信时才会发送 Cookie。 | Secure (无值,仅需存在即可生效) |
HttpOnly | 限制 Cookie 不能被 JavaScript 脚本访问,防止 XSS 攻击。 | HttpOnly (无值,仅需存在即可生效) |
- expires 属性
Cookie 的 expires 属性指定浏览器可发送 Cookie 的有效期。
当省略 expires 属性时,其有效期仅限于维持浏览器会话(Session) 时间段内。
这通常限于浏览器应用程序被关闭之前。
另外,一旦 Cookie 从服务器端发送至客户端,服务器端就不存在可 以显式删除 Cookie 的方法。但可通过覆盖已过期的 Cookie,实现对 客户端 Cookie 的实质性删除操作。
- path 属性
Cookie 的 path 属性可用于限制指定 Cookie 的发送范围的文件目录。
不过另有办法可避开这项限制,看来对其作为安全机制的效果不能抱 有期待。
- domain 属性
通过 Cookie 的 domain 属性指定的域名可做到与结尾匹配一致。
比 如,当指定 example.com 后,除 example.com 以外,www.example.com 或 www2.example.com 等都可以发送 Cookie。
因此,除了针对具体指定的多个域名发送 Cookie 之 外,不指定 domain 属性显得更安全。
- secure 属性
Cookie 的 secure 属性用于限制 Web 页面仅在 HTTPS 安全连接时,才 可以发送 Cookie。 130 发送 Cookie 时,指定 secure 属性的方法如下所示。
Set-Cookie: name=value; secure
以上例子仅当在 https://www.example.com/(HTTPS)安全连接的情况 下才会进行 Cookie 的回收。
也就是说,即使域名相同, http://www.example.com/(HTTP)也不会发生 Cookie 回收行为。
当省略 secure 属性时,不论 HTTP 还是 HTTPS,都会对 Cookie 进行 回收。
- HttpOnly 属性
Cookie 的 HttpOnly 属性是 Cookie 的扩展功能,它使 JavaScript 脚本 无法获得 Cookie。
其主要目的为防止跨站脚本攻击(Cross-site scripting,XSS)对 Cookie 的信息窃取。
发送指定 HttpOnly 属性的 Cookie 的方法如下所示。
Set-Cookie: name=value; HttpOnly
通过上述设置,通常从 Web 页面内还可以对 Cookie 进行读取操作。
但使用 JavaScript 的 document.cookie 就无法读取附加 HttpOnly 属性后 的 Cookie 的内容了。
因此,也就无法在 XSS 中利用 JavaScript 劫持 Cookie 了。
虽然是独立的扩展功能,但 Internet Explorer 6 SP1 以上版本等当下的 主流浏览器都已经支持该扩展了。另外顺带一提,该扩展并非是为了 防止 XSS 而开发的。
7.2.Cookie
Cookie: status=enable
首部字段 Cookie 会告知服务器,当客户端想获得 HTTP 状态管理支 持时,就会在请求中包含从服务器接收到的 Cookie。
接收到多个 Cookie 时,同样可以以多个 Cookie 形式发送