(转)《图解HTTP》第5-6章笔记

摘要

《图解HTTP》第5-6章笔记,特此记录重要部分。

第5章 与HTTP协作的Web服务器

一台Web服务器可搭建多个独立域名的Web网站,也可作为通信路径上的中转服务器提升传输效率。

5.1 用单台虚拟主机实现多个域名

HTTP/1.1规范允许一台HTTP服务器搭建多个Web站点。

在互联网上,域名通过DNS服务映射到IP地址(域名解析)之后访问目标网站。可见,当请求发送到服务器时,已经是以IP地址形式访问了。


所以如果一台服务器内托管了两个域名,当收到请求时就需要弄清楚究竟要访问哪个域名。

在相同的IP地址下,由于虚拟主机可以寄存多个不同主机名和域名的Web网站,因此在发送HTTP请求时,必须在Host首部内完整指定主机名或域名的URI。

5.2 通信数据转发程序:代理、网管、隧道

  • 代理:代理是一种有转发功能的应用程序。

  • 网关:网关是转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。

  • 隧道:隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序。

5.2.1 代理


在HTTP通信过程中,可级联多台代理服务器。请求和响应的转发会经过数台类似锁链一样连接起来的代理服务器。转发时,需要附加Via首部字段以标记出经过的主机信息。

使用代理服务器的理由有:利用缓存技术减少网络带宽的流量,组织内部针对特定网站的访问控制,以获取访问日志为主要目的等等。

代理按两种基准分类。一种是是否使用缓存,另一种是是否会修改报文。

  • 缓存代理:代理转发响应时,缓存代理(Caching Proxy)会预先将资源的副本(缓存)保存在代理服务器上。当代理再次接收到对相同资源的请求时,就可以不从源服务器那里获取资源,而是将之前缓存的资源作为响应返回。

  • 透明代理:转发请求或响应时,不对报文做任何加工的代理类型被称为透明代理(Transparent Proxy)。反之,对报文内容进行加工的代理被称为非透明代理。

5.2.2 网关


网关能使通信线路上的服务提供非HTTP协议服务。(比如利用网关可以由HTTP请求转化为其他协议通信)

利用网关能提高通信的安全性,因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。

5.2.3 隧道

隧道可按要求建立起一条与其他服务器的通信线路,届时使用SSL等加密手段进行通信。


隧道的目的是确保客户端能与服务器进行安全的通信。

隧道本身不会去解析HTTP请求。请求保持原样中转给之后的服务器。隧道会在通信双方断开连接时结束。

5.3 保存资源的缓存

缓存是指代理服务器或客户端本地磁盘内保存的资源副本。

缓存服务器是代理服务器的一种,并归类在缓存代理类型中。

5.3.1 缓存的有效期限

即使存在缓存,也会因为客户端的要求、缓存的有效期等因素,向源服务器确认资源的有效性。

5.3.2 客户端的缓存

缓存不仅可以存在于缓存服务器中,还可以存在客户端浏览器中。以Internet Explorer程序为例,把客户端缓存称为临时网络文件(Temporary Internet File)。

浏览器缓存如果有效,就不必再向服务器请求相同的资源了,可以直接从本地磁盘内读取。

第6章 HTTP首部

6.1 HTTP报文首部

HTTP请求报文:由方法、URI、HTTP版本、HTTP首部字段(请求首部字段、通用首部字段、实体首部字段)等部分构成。

HTTP响应报文:由HTTP版本、状态码(数字和原因短语)、HTTP首部字段(响应首部字段、通用首部字段、实体首部字段)等部分构成。

6.2 HTTP首部字段

6.2.2 HTTP首部字段结构

首部字段名:字段值

1
2
Content-Type:text/html
Content-Type:表示报文主体的对象类型。

字段值也可以对应单个HTTP首部字段可以由多个值

1
Keep-Alive:timeout=15,max=100

6.2.3 4种HTTP首部字段类型

  1. 通用首部字段:请求报文和响应报文两方都会使用的首部。

  2. 请求首部字段:从客户端向服务器端发送请求报文时使用的首部。

  3. 响应首部字段:从服务器端向客户端返回响应报文时使用的首部。

  4. 实体首部字段:针对请求报文和响应报文的实体部分使用的首部。

6.2.4 HTTP/1.1 首部字段一览

1.通用首部字段

1
2
3
4
5
6
7
8
9
Cache-Control:控制缓存的行为
Connection:逐跳首部、连接的管理
Date:创建报文的日期时间
Pragma:报文指令
Trailer:报文末端的首部一览
Trasfer-Encoding:指定报文主题的传输编码方式
Upgrade:升级为其他协议
Via:代理服务器的相关信息
Warning:错误通知

2.请求首部字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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-Forwads:最大传输逐跳数
Proxy-Authorization:代理服务器要求客户端的认证信息
Range:实体的字节范围请求
Referer:对请求中URI的原始获取方
TE:传输编码的优先级
User-Agent:HTTP客户端程序的信息

3.响应首部字段

1
2
3
4
5
6
7
8
9
Accept-Ranges:是否接受字节范围请求
Age:推算资源创建经过时间
ETag:资源的匹配信息
Location:令客户端重定向至指定URI
Proxy-Authenticate:代理服务器对客户端的认证信息
Retry-After:对再次发起请求的时机要求
Server:HTTP服务器的安装信息
Vary:代码服务器缓存的管理信息
WWW-Authenticate:服务器对客户端的认证信息

4.实体首部字段

1
2
3
4
5
6
7
8
9
10
Allow:资源可支持的HTTP方法
Content-Encoding:实体主体适用的编码方式
Content-Language:实体主体的自然语言
Content-Length:实体主体的大小(单位:字节)
Content-Location:替代对应资源的URI
Content-MD5:实体主体的报文摘要
Content-Range:实体主体的位置范围
Content-Type:实体主体的媒体类型
Expires:实体主体过期的日期时间
Last-Modified:资源最后修改日期时间

6.2.5 非HTTP/1.1首部字段

非正式的首部字段统一归纳在RFC4229 HTTP Header Field Registrations中,如

Cookie、Set-Cookie、Content-Disposition

6.2.6 End-to-end首部和Hop-by-hop首部

HTTP首部字段将定义成缓存代理和非缓存代理的行为,分为2种类型。

  • 端到端首部(end-to-end header):分在此类别中的首部会转发给请求/响应对应的最终接收目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发。

  • 逐跳首部(hop-by-hop header):分在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再转发。HTTP/1.1和之后的版本中,如果要使用hop-by-hop首部,需提供Connection首部字段。

除以下8个首部字段之外,其他所有字段都属于端到端首部(end-to-end header)。

  • Connection
  • Keep-Alive
  • Proxy-Authenticate
  • Proxy-Authorization
  • Trailer
  • TE
  • Transfer-Encoding
  • Upgrade

6.3 HTTP/1.1通用首部字段

6.3.1 Cache-Control

操作缓存的工作机制。

指令的参数是可选的,多个指令之间通过“,”分隔。

Cache-Control:private,max-age=0,no-cache

1.缓存请求指令

指令 参数 说明
no-cache 强制向源服务器再次验证
no-store 不缓存请求或响应的任何内容
max-age=[秒] 必需 响应的最大Age值
max-stale=[秒] 可省略 接收已过期的响应
min-fresh=[秒] 必需 期望在指定时间内的响应仍有效
no-transform 代理不可更改媒体类型
only-if-cached 从缓存获取资源
cache-extension - 新指令标记(token)

2.缓存响应指令

指令 参数 说明
public 可向任一方提供响应的缓存
private 可省略 仅向特定用户返回响应
no-cache 可省略 缓存前必须先确认其有效性
no-store 不缓存请求或响应的任何内容
no-transform 代理不可更改媒体类型
must-revalidate 可缓存但必须向源服务器进行确认
proxy-revalidate 要求中间缓存服务器对缓存的响应有效性再进行确认
max-age=[秒] 必需 响应的最大Age值
s-maxage=[秒] 必需 公共缓存服务器响应的最大Age值
cache-extension - 新指令标记(token)
表示是否能缓存的指令:public指令、private指令、no-cache指令
public指令(缓存响应指令)

Cache-Control:public

当指定使用public时,则明确表明其他用户也可利用缓存。

private指令(缓存响应指令)

Cache-Control:private

当指定private指令后,响应只以特定的用户作为对象,这与public指令的行为相反。

缓存服务器会对该特定用户提供资源缓存的服务,对于其他用户发送过来的请求,代理服务器则不会返回缓存。

no-cache指令(缓存请求/响应指令)

Cache-Control:no-cache

客户端发送的请求中包含no-cache指令,则表示客户端将不会接收缓存过的响应。

服务器返回的响应中包含no-cache指令,那么缓存服务器不能对资源进行缓存。源服务器以后也将不再对缓存服务器请求中提出的资源有效性进行确认,且禁止其对响应资源进行缓存操作。

Cache-Control:no-cache=Location

由服务器返回的响应中,若报文首部字段Cache-Control中对no-cache字段名具体指定参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存。换言之,无参数值的首部字段可以使用缓存。

no-cache代表不缓存过期的资源,缓存会向源服务器进行有效期确认后处理资源。 控制可执行缓存的对象的指令:no-store指令
no-store指令(缓存请求/响应指令)

Cache-Control:no-store

no-store指令才是真正地不进行缓存。

指令缓存期限和认证的指令:s-maxage指令、max-age指令、min-fresh指令、max-stale指令、only-if-cached指令、must-revalidate指令、proxy-revalidate指令、no-transform指令
s-maxage指令(缓存响应指令)

Cache-Control:s-maxage=604800(单位:秒)

s-maxage指令的功能和max-age指令的相同,它们的不同点是s-maxage指令只适用于供多为用户使用的公共缓存服务器(这里一般指代理)。也就是说,对于向同一用户重复返回响应的服务器来说,这个指令没有任何作用。

另外,当使用s-maxage指令后,则直接忽略对Expires首部字段及max-age指令的处理。

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指令会被忽略掉。

min-fresh指令(缓存请求指令)

Cache-Control:min-fresh=60(单位:秒)

min-fresh指令要求缓存服务器返回至少还未过指定时间的缓存资源。

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指令无论是在请求还是在响应中,缓存都不能改变实体主体的媒体类型。这样可以防止缓存或代理压缩图片等类似操作。

cache-extension token

Cache-Control:private,community="UCI"

通过cache-extension标记(token),可扩展Cache-Control首部字段内的指令。

如上例,Cache-Control首部字段本身没有community这个指令。借助extension token实现了该指令的添加。如果缓存服务器不能理解community这个新指令,则会直接忽略。因此,extension token仅对能理解它的缓存服务器来说是有意义的。

6.3.2 Connection

Connection首部字段具备如下两个作用。

  • 控制不再转发给代理的首部字段
  • 管理持久连接

1.控制不再转发给代理的首部字段

Connection:不再转发的首部字段名

在客户端发送请求和服务器返回响应内,使用Connection首部字段,可控制不再转发给代理的首部字段(即hop-by-hop首部)。

2.管理持久连接

Connection:close

HTTP/1.1版本的默认连接都是持久连接。为此,客户端会在持久连接上连续发送请求。当服务器端向明确断开连接时,则指定Connection首部字段值为close。

Connection:Keep-Alive

HTTP/1.1之前的HTTP版本的默认连接都是非持久连接。为此,如果想在旧版本的HTTP协议上维持持续连接,则需要指定Connection首部字段的值为Keep-Alive。

6.3.3 Date

首部字段Date表明创建HTTP报文的日期和时间。

6.3.4 Pragma

Pragma是HTTP/1.1之前版本的历史遗留字段,仅作为与HTTP/1.0的向后兼容而定义。

规范定义的形式唯一,如下

Pragma:no-cache

该首部字段属于通用首部字段,但只用在客户端发送的请求中。客户端会要求所有的中间服务器不返回缓存的资源。

6.3.5 Trailer

首部字段Trailer会事先说明在报文主题后记录了哪些首部字段。该首部字段可应用在HTTP/1.1版本分块传输编码时。

6.3.6 Transfer-Encoding

首部字段Transfer-Encoding规定了传输报文主体时采用的编码方式。

HTTP/1.1的传输编码方式仅对分块传输编码有效。

6.3.7 Upgrade

首部字段Upgrade用于检测HTTP协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。

请求:

1
2
3
GET /index.htm HTTP/1.1
Upgrade:TSL/1.0
Connection:Upgrade

响应:

1
2
3
HTTP/1.1 101 Switching Protocols
Upgrade:TSL/1.0 HTTP/1.1
Connection:Upgrade

上例中首部字段Upgrade指定的值为TSL/1.0。请注意此处两个字段首部的对应关系,Connection的值被指定为Upgrade。Upgrade首部字段产生作用的Upgrade对象仅限于客户端和邻接服务器之间。因此,使用首部字段Upgrade时,还需要额外指定Connection:Upgrade。

6.3.8 Via

使用首部字段Via是为了追踪客户端与服务器之间的请求和响应报文的传输路径。

报文经过代理或网关时,会现在首部字段Via中附加该服务器的信息,然后再进行转发。

首部字段Via不仅用于追踪报文的转发,还可避免请求回环的发生。

6.3.9 Warning

HTTP/1.1的Warning首部是从HTTP/1.0的响应首部(Retry-After)演变过来的。该首部通常会告知用户一些与缓存相关的问题的警告。

6.4 请求首部字段

6.4.1 Accept

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。

可使用type/subtype这种形式,一次指定多种媒体类型。

若想要给显示的媒体类型增加优先级,则使用q=来额外表示权重值,用分号(;)进行分隔。权重值q的范围是0~1(可精确到小数点后3位),且1为最大值。不指定权重q值时,默认权重为q=1.0。

当服务器提供多种内容时,将会首先返回权重值最高的媒体类型。

6.4.2 Accept-Charset

Accept-Charset:iso-8859-5,unicode-1-1;q=0.8

Accept-Charset首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。另外,可一次性指定多种字符集。

可用权重q值来表示相对优先级。

6.4.3 Accept-Encoding

Accept-Encoding:gzip,deflate

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值来表示相对优先级。另外,也可使用星号(*)作为通配符,指定任意的编码格式。

#### 6.4.4 Accept-Language

Accept-Language:zh-cn,zh;q=0.7,en-us,en;q=0.3

首部字段Accept-Language用来告知服务器用户代理能够处理的自然语言集(指中文或英文等),以及自然预言集的相对优先级。可一次指定多种自然语言集。

用权重值q来表示相对优先级。

#### 6.4.5 Authorization

Authorization:Basic dWVub3N1bjpwYXNzd29yZA==
首部字段Authorization是用来告知服务器,用户代理的认证信息(证书值)。通常,想要通过服务器认证的用户代理会在接收到返回的401状态码响应后,把首部字段Authorization加入请求中。共用缓存在接收到含有Authorization首部字段的请求时的操作处理会略有差异。

#### 6.4.6 Expect

Expect:100-continue

客户端使用首部字段Expect来告知服务器,期望出现的某种特定行为。因服务器无法理解客户端的期望作出回应而发生错误时,会返回状态码417 Expectation Failed。

客户端可以利用该首部,写明所期望的扩展。虽然HTTP/1.1规范之定义了100-continue(状态码 100 Continue之意)。

等待状态码100响应的客户端在发生请求时,需要指定Expect:100-continue。

#### 6.4.7 From

From:info@hackr.jp

首部字段From用来告知服务器使用用户代理的用户的电子邮件地址。

#### 6.4.8 Host

Host:www.hackr.jp

首部字段Host会告知服务器,请求的资源所处的互联网主机名和端口号。Host首部字段在HTTP/1.1规范内是唯一一个必须被包含在请求内的首部字段。

首部字段Host和以单台服务器分配多个域名的虚拟主机的工作机制有很密切的联系。

请求被发送至服务器时,请求中的主机名会用IP地址直接替换解决。但如果这时,相同的IP地址下部署运行着多个域名,那么服务器就会无法理解究竟是哪个应对应的请求。因此,就需要使用首部字段Host来明确指出请求的主机名。若服务器未设定主机名,那直接发送一个空值即可。

6.4.9 If-Match

If-Match:"123456"

首部字段If-Match,属附带条件之一,它会告知服务器匹配资源所用的实体标记(ETag)的值。这时的服务器无法使用弱ETag值。

服务器会比对If-Match的字段值和资源的ETag值,仅当两者一致时,才会执行请求。反之,则返回状态码412 Precondition Failed的响应。

还可以使用星号(*)指定If-Match的字段值。针对这种情况,服务器将会忽略ETag的值,只要资源存在就处理请求。

6.4.10 If-Modified-Since

GET /index.htm 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来确定。

6.4.11 If-None-Match

首部字段If-None-Match属于附带条件之一。它和首部字段If-Match作用相反。用于指定If-None-Match字段值的实体标记(ETag)值与请求资源的ETag不一致时,它就告知服务器处理该请求。

在GET或HEAD方法中使用首部字段If-None-Match可获取最新的资源。

6.4.12 If-Range

首部字段If-Range属于附带条件之一。它告知服务器若指定的If-Range字段值(ETag值或者时间)和请求资源的ETag值或时间相一致时,则作为范围请求处理。反之,则返回全体资源。

如果不使用首部字段If-Range则需要进行两次处理。1.用状态码412 Precondition Failed作为响应返回,其目的是催促客户端再次发送请求。2.再次请求。

6.4.13 If-Unmodified-Since

作用是告知服务器,指定的请求资源只有在字段值内指定的日期时间之后,未发生更新的情况下,才能处理请求。如果在指定日期时间后发生了更新,则以状态码412 Precondition Failed作为响应返回。

6.4.14 Max-Forwards

Max-Forwards:10

通过TRACE方法或OPTIONS方法,发送包含首部字段Max-Forwards的请求时,该字段以十进制整数形式指定可经过的服务器最大数目。服务器在往下一个服务器转发请求之前,Max-Forwards的值减1后重新赋值。当服务器收到Max-Forwards值为0的请求时,则不再进行转发,而是直接返回响应。

使用HTTP协议通信时,请求可能会经过代理等多台服务器。途中,如果代理服务器由于某些原因导致请求转发失败,客户端也就等不到服务器返回的响应了。因此我们可以灵活使用首部字段Max-Forwards。由于当Max-Forwards字段值为0时,服务器就会立即返回响应,由此我们至少可以对以那台服务器为终点的传输路径的通信情况有所把握。

6.4.15 Proxy-Authorization

Proxy-Authorization:Basic dGlwOjkpNLAGfFY5

接收到从代理服务器发来的认证质询时,客户端会发送包含首部字段Proxy-Authorization的请求,以告知服务器认证所需要的信息。

认证行为发生在客户端与代理之间。

客户端与服务器之间的认证,使用首部字段Authorization可起到相同作用。

6.4.16 Range

对于只需获取部分资源的范围请求,包含首部字段Range即可告知服务器资源的指定范围。

接收到附带Range首部字段请求的服务器,会在处理请求之后返回状态码为206 Partial Content的响应。无法处理该范围请求时,则会返回状态码200 OK的响应及全部资源。

6.4.17 Referer

Referer:http://www.hackr.jp/index.htm

首部字段Referer会告知服务器请求的原始资源的URI。

客户端一般都会发送Referer首部字段给服务器。但当直接在浏览器的地址栏输入URI,或处于安全性的考虑时,也可以不发送该首部字段。

因为原始资源的URI中的查询字符串可能包含有ID和密码等保密信息,要是写进Referer转发给其他服务器,则有可能导致保密信息的泄露。

6.4.18 TE

TE:gzip,deflate;q=0.5

首部字段TE会告知服务器客户端能够处理响应的传输编码方式及相对优先级。它和首部字段Accept-Encoding的功能很像,但是用于传输编码。

首部字段TE除指定传输编码之外,还可以指定伴随trailer字段的分块传输编码的方式。

TE:trailers

#### 6.4.19 User-Agent

首部字段User-Agent会将创建请求的浏览器和用户代理名称等信息传达给服务器。

### 6.5 响应首部字段

#### 6.5.1 Accept-Ranges

Accept-Ranges:bytes

首部字段Accept-Ranges是用来告知客户端服务器是否能处理范围的请求,以指定获取服务器端某个部分的资源。

可指定的字段值有两种,可处理范围请求时指定其为bytes,反之则指定其为none。

#### 6.5.2 Age

Age:600(单位为秒)

首部字段Age能告知客户端,源服务器在多久前创建了响应。

若创建该响应的服务器是缓存服务器,Age值是指缓存后的响应再次发起认证到认证完成的时间值。

代理创建响应时必须加上首部字段Age。

6.5.3 ETag

ETag:"82e22293907ce....."

首部字段ETag能告知客户端实体的标识。它是一种可将资源以字符串形式做唯一标识的方式。服务器会为每份资源分配对应的ETag值。

另外,当资源更新时,ETag值也需要更新。生成ETag值时,并没有统一的算法规则,而仅仅是由服务器来分配。

##### 强ETag值

强ETag值,不论实体发生多么细微的变化都会改变其值。

ETag:"usagi-1234"

##### 弱ETag值

弱ETag值只用于提示资源是否相同。只有资源发生了根本改变,产生差异时才会改变ETag值。这时,会在字段值最开始处附加W/。

ETag:W/"usagi-1234"

#### 6.5.4 Location

使用首部字段Location可以将响应接收方引导至某个请求URI位置不同的资源。

基本上,该字段会配合3xx:Redirection的响应,提供重定向的URI。

几乎所有的浏览器在接收到包含首部字段Location的响应后,都会强制性地尝试对已提示的重定向资源的访问。

#### 6.5.5 Proxy-Authenticate

Proxy-Authenticate:Basic realm="Usagidesign Auth"

首部字段Proxy-Authenticate会把由代理服务器所要求的认证信息发送给客户端。

客户端与服务器之间的认证,通过首部字段WWW-Authorization。

#### 6.5.6 Retry-After

Retry-After:120

首部字段Retry-After告知客户端应该在多久之后再次发送请求。主要配合状态码503 Service Unavailiavle响应,或3xx Redirect 响应一起使用。

字段值可以指定为具体的日期时间(Web,04 Jul 2012 06:34:24 GMT),也可以是创建响应后的秒数。

#### 6.5.7 Server

Server:Apache/2.2.17(Unix)

首部字段Server告知客户端当前服务器上安装的HTTP服务器应用程序的信息。不单单会标出服务器上的软件应用名称,还有可能包括版本号和安装时启动的可选项。

#### 6.5.8 Vary

首部Vary可对缓存进行控制。

当代理服务器接收到带有Vary首部字段指定获取资源的请求时,如果使用的Accept-Language字段的值相同,那么就直接从缓存返回响应。反之,则需要先从源服务器端获取资源后才能作为响应返回。

从代理服务器接收到源服务器返回包含Vary指定项的响应之后,若再要进行缓存,仅对请求中含有相同Vary指定首部字段的请求返回缓存。即使对相同资源发起请求,但由于Vary指定的首部字段不相同,因此必须要从源服务器重新获取资源。

#### 6.5.9 WWW-Authenticate

WWW-Authenticate:Basic realm="Usagidesign Auth"

首部字段WWW-Authenticate用于HTTP访问认证。它会告知客户端适用于访问请求URI所指定资源的认证方案(Basic或是Digest)和带参数提示的质询(challenge)。状态码401 Unauthorized的响应中,肯定带有首部字段WWW-Authenticate。

### 6.6 实体首部字段

实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。

#### 6.6.1 Allow

Allow:GET,HEAD

首部字段Allow用于通知客户端能够支持Request-URI指定资源的所有HTTP方法。当服务器收到不支持的HTTP方法时,会以状态码405 Method Not Allowed作为响应返回。与此同时,还会把所有能支持的HTTP方法写入首部字段Allow后返回。

#### 6.6.2 Content-Encoding

Content-Encoding:gzip

首部字段Content-Encoding会告知客户端服务器对实体的主体部分选用的内容编码方式。

#### 6.6.3 Content-Language

Content-Language:zh-CN

首部字段Content-Language会告知客户端,实体主体使用的自然语言(指中文或英文等语言)。

#### 6.6.4 Content-Length

Content-Length:15000(单位:字节)

首部字段Content-Length表明了实体主体部分的大小。对实体主体进行内容编码传输时,不能再使用Content-Length首部字段。

#### 6.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.6 Content-MD5

首部字段Content-MD5是一串由MD5算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。

对报文主体执行MD5算法获得的128位二进制数,再通过Base64编码后将结果写入Content-MD5字段值。由于HTTP首部无法记录二进制值,所以要通过Base64编码处理。为确保报文的有效性,作为接收方的客户端会对报文主体再执行一次相同的MD5算法。

采用这种方式,对内容上的偶发性改变是无从查证的,也无法检测出恶意篡改。

6.6.7 Content-Range

Content-Range:bytes 50001-10000/10000

针对范围请求,返回响应时使用的首部字段Content-Range,能告知客户端作为响应返回的实体的哪个部分符合范围的骑牛。字段值以字节为单位,表示当前发送部分及整个实体大小。

6.6.8 Content-Type

Content-Type:text/html;charset=UTF-8

首部字段Content-Type说明了实体主体内对象的媒体类型。和首部字段Accept一样,字段值用type/subtype形式赋值。

参数charset使用iso-8859-1或euc-jp等字符集进行赋值。

6.6.9 Expires

Expires:Wed,04 Jul 2012 08:26:05 GMT

首部字段Expires会将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段Expires的响应后,会以缓存来应答请求,在Expires字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。


源服务器不希望缓存服务器对资源缓存时,最好在Expires字段内写入与首部字段Date相同的时间值。

但是,当首部字段Cache-Control有指定max-age指令时,比起首部字段Expires,会优先处理max-age指令。

6.6.10 Last-Modified

首部字段Last-Modified指定资源最终修改的时间。

其他

Accept-Encoding 和 Content-Encoding

HTTP 协议中的 Content-Encoding

Accept-Encoding 和 Content-Encoding 是 HTTP 中用来对「采用何种编码格式传输正文」进行协定的一对头部字段。它的工作原理是这样:浏览器发送请求时,通过 Accept-Encoding 带上自己支持的内容编码格式列表;服务端从中挑选一种用来对正文进行编码,并通过 Content-Encoding 响应头指明选定的格式;浏览器拿到响应正文后,依据 Content-Encoding 进行解压。当然,服务端也可以返回未压缩的正文,但这种情况不允许返回 Content-Encoding。这个过程就是 HTTP 的内容编码机制。

Transfer-Encoding

HTTP 协议中的 Transfer-Encoding