HTTP首部字段详解
HTTP首部字段详解
在HTTP/1.1规范中定义了47种首部字段,总共分为四大类:
- 通用首部字段 —— 请求报文和响应报文两方都会使用的首部
- 请求首部字段 —— 从客户端向服务器端发送请求报文时使用的首部。补充了
请求的附加内容
、客户端信息、响应内容相关优先级
等信息 - 响应首部字段 —— 从服务器端向客户端返回响应报文时使用的首部。补充了
响应的附加内容
,也会要求客户端附加额外的内容信息 - 实体首部字段 —— 针对
请求报文和响应报文的实体部分
使用的首部。补充了资源内容更新时间等与实体有关的信息
通用首部字段
Cache-Control
通过多个可选的指令参数实现对缓存服务器的缓存行为的控制。
Cache-Control指令可用于请求及响应时,因此Cache-Control指令可分为请求指令和响应指令。
缓存请求指令
no-cache
—— 防止从缓存中返回过期的资源。
- 从客户端的角度来说,如果发送的请求中包含no-cache指令,则表示客户端不会接收缓存过的响应。所以,后续的请求都要求缓存服务器把客户端请求转发给源服务器。
- 从服务器的角度来说,如果服务器返回的响应中包含no-cache指令,那么缓存服务器不能对资源进行缓存。源服务器以后也将不再对缓存服务器请求中提出的资源有效性进行确认,且禁止其对响应资源进行缓存操作。
no-store
—— 真正意义上的不缓存,该指令规定缓存不能在本地存储请求或响应的任一部分。
max-age
—— 代表资源保存为缓存的最长时间
- 从客户端的角度,当客户端发送的请求中包含max-age指令时,如果判定缓存服务器上的缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存资源。当max-age值为0时,缓存服务器通常需要将请求转发给源服务器。
- 从服务端的角度,当服务器返回的响应中包含 max-age 指令时,缓存服务器将不对资源的有效性再作确认,在max-age时间内可直接支配缓存。
min-fresh
—— 要求缓存服务器返回至少还未过指定时间的缓存资源,即指定时间内仍不会过期的缓存资源。
缓存响应指令
public
—— 表明是共享缓存,其他用户也可使用该缓存
private
—— 独占缓存,服务器的响应只以特定的用户作为对象
,缓存服务器会对该特定用户提供资源缓存的服务,对于其他用户发送过来的请求,代理服务器则不会返回缓存。
must-revalidate
—— 代理会向源服务器再次验证
即将返回的响应缓存目前是否仍然有效。
proxy-revalidate
—— 要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性。
Connection
两个作用:
-
控制
不再转发
给代理的首部字段 -
管理持久连接
HTTP/1.1版本的
默认连接就是持久连接
。因此,客户端会在持久连接上连续发送请求
。 当服务器端想明确断开连接时,则指定Connection首部字段的值为 Close。另外,如果想在旧版本的HTTP协议上维持持久连接,则需要指定Connection首部字段的值为
Keep-Alive
。
Date
表明创建HTTP报文的日期和时间。有两种格式:
-
HTTP/1.1采用RFC1123中规定的格式
-
之前的版本使用RFC850中规定的格式
Transfer-Encoding
规定了传输报文主体时采用的编码方式。
ps: HTTP/1.1的传输编码方式仅对分块传输编码有效
。
正如上面的响应报文在首部字段 Transfer-Encoding 中指定的那样,有效使用分块传输编码
,且分别被分成 3312 字节和 914 字节大小的分块数据。
Upgrade
用于检测 HTTP 协议及其他协议是否可使用更高的版本进行通信
,其参数值可以用来指定一个完全不同的通信协议。例如下图,仅作用在客户端和邻接服务器之间的请求中的Upgrade字段指定的值为TLS/1.0,邻接服务器的响应中的Upgrade字段值为TLS/1.0和HTTP/1.1。
Via
追踪
客户端与服务器之间的请求和响应报文的传输路径
,简单来说就是追踪报文的转发,避免请求回环的发生。报文经过代理或网关时,会先在首部字段 Via 中附加该服务器的信息,然后再进行转发。
Via 首部是为了追踪传输路径,所以经常会和 TRACE请求方法一起使用。
Warning
通常会告知用户一些与缓存相关的问题的警告。
请求首部字段
内容协商
Accept
通知服务器,用户代理能够处理的媒体类型
及媒体类型的相对优先级
。 可使用 type/subtype 这种形式,一次指定多种媒体类型(MIME类型)。
MIME类型数据
MIME类型一般会和属性q
一起使用,q
表示的是权重,没使用属性q
则默认权重为1.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
上面的Accept标头内容对应如下表格:
q | MIME |
---|---|
1.0 | text/html |
1.0 | application/xhtml+xml |
0.9 | application/xml |
0.8 | / |
Accept-Charset
客户端能接受的字符编码。
Accept-Encoding
希望服务端返回的内容编码,通常是一种压缩算法,同样采用权重 q 值来表示采用压缩算法的相对优先级。
- gzip —— 由文件压缩程序 gzip(GNU zip)生成的编码格式(RFC1952), 采用 Lempel-Ziv 算法(LZ77)及 32 位循环冗余校验(Cyclic Redundancy Check,通称 CRC)。
- compress —— UNIX 文件压缩程序 compress 生成的编码格式,采用 LempelZiv-Welch 算法(LZW)。
- deflate —— 组合使用 zlib 格式(RFC1950)及由 deflate 压缩算法(RFC1951) 生成的编码格式。
- identity —— 不执行压缩或不会变化的默认编码格式。
Accept-Language
客户端需要服务端返回的语言类型,同样采用权重 q 值来表示希望接收的自然语言类别的相对优先级。
授权
Authorization
首部字段 Authorization 是用来告知服务器,用户代理的认证信息(证书值)。通常,想要通过服务器认证的用户代理会在接收到返回的 401 状态码响应后,把首部字段 Authorization 加入请求中
。
通信信息
From
告知服务器使用用户代理的用户的电子邮件地址。
Host
告知服务器,请求的资源所处的互联网主机名和端口号。Host 首部字段在 HTTP/1.1 规范内是唯一一个必须被包含在请求内的首部字段。
Host字段的存在意义
—— 通常单台服务器会分配多个域名的虚拟主机,Host字段能帮助区分虚拟主机。
User-Agent
创建请求的浏览器和用户代理名称等信息传达给服务器。
附加条件请求
形如 If-xxx 这种样式的请求首部字段,都可称为条件请求。服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
If-Match
只有当 If-Match 的字段值跟 ETag 值匹配一致时,服务器才会接受请求。
还可以使用星号(*)指定 If-Match 的字段值。针对这种情况,服务器将会忽略 ETag 的值,只要资源存在就处理请求。
If-Modified-Since
告知服务器若 If-Modified-Since 字段值早于资源的更新时间,则希望能处理该请求。而在指定 If-Modified-Since 字段值的日期时间之后,如果请求的资源都 没有过更新,则返回状态码 304 Not Modified 的响应。
If-Modified-Since 用于确认代理或客户端拥有的本地资源的有效性。
If-Unmodified-Since
告知服务器,指定的请求资源只有在字段值内指定的日期时间之后,未发生更新的情况下,才能处理请求。
If-None-Match
和首部字段If-Match的作用恰恰相反。当指定 If-None-Match 字段值的实体标记(ETag) 值与请求资源的 ETag 不一致时,它就告知服务器处理该请求。因此,在GET或HEAD方法中使用首部字段If-None-Match可获取最新的资源
。
If-Range
告知服务器若指定的 If-Range 字段值(ETag 值或者时间)和请求资源的 ETag 值或时间相一 致时,则作为范围请求处理。反之,则返回全体资源。
不使用If-Range发送请求的情况
:
服务器端的资源如果更新,那客户端持有资源中的一部分也会随之无效。这时,服务器会暂且以状态码 412 Precondition Failed 作为响应返回,其目的是催促客户端再次发送请求。 这样一来,与使用首部字段 If-Range 比起来,就需要花费两倍的功夫。
范围请求
Range
对于只需获取部分资源的范围请求,包含首部字段 Range 即可告知服务器资源的指定范围。下面的示例表示请求获取从第 5001 字节至第 10000 字节的资源。服务端的请求结果有两种:
- 成功处理该范围请求 —— 返回206 Partial Content响应和请求要求的相应范围的资源。
- 无法处理该范围请求 —— 返回200 OK响应和全部资源。
响应首部字段
响应首部字段是由服务器端向客户端返回响应报文中所使用的字 段,用于补充响应的附加信息、服务器信息,以及对客户端的附加要求 等信息,本文重点介绍以下字段:
范围请求的响应
关于HTTP响应状态码的详解请参考前篇HTTP请求方法及响应状态码详解
Accept-Ranges
告知客户端服务器是否能处理范围请求,以指定获取服务器端某个部分的资源。
-
能处理范围请求时,
Accept-Ranges:bytes
-
不能处理范围请求时,
Accept-Ranges:none
缓存相关响应
Age
告知客户端,源服务器在多久前创建了响应。字段值的单位为秒。
响应实体相关
ETag
告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识
的方式。服务器会为每份资源分配对应的 ETag 值。 另外,当资源更新时,ETag 值也需要更新。
强ETag vs 弱ETag值
- 强ETag值 —— 不论实体发生多么细微的变化都会改变其值。
- 弱ETag值 —— 只用于提示资源是否相同。只有资源发生了根本改变,产生差异时才会改变 ETag 值。这时,会在字段值最开始处附加 W/。
资源定位相关
Location
将响应接收方引导至某个与请求 URI 位置不同的资源。
基本上,该字段会配合 3xx :Redirection 的响应,提供重定向的 URI。
几乎所有的浏览器在接收到包含首部字段 Location 的响应后,都会强制性地尝试对已提示的重定向资源的访问。
实体首部字段
实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息
。
资源支持的HTTP请求方法
Allow
通知客户端能够支持 Request-URI 指定资源的所有 HTTP 方法
。
当服务器接收到不支持的 HTTP 方法时,会以状态码405 Method Not Allowed
作为响应返回。与此同时,还会把所有能支持 的 HTTP 方法写入首部字段 Allow 后返回。
实体主体相关
Content-Encoding
告知客户端服务器对实体的主体部分选用的内容编码方式
。内容编码是指在不丢失实体信息的前提下
所进行的压缩。常用的压缩方法有gzip、compress、deflate、identity。
Content-Language
告知客户端,实体主体使用的自然语言(指中文或英文等语言)。
Content-Length
表明了实体主体部分的大小(单位是字节)。
Content-Location
和 首部字段 Location 不同,Content-Location 表示的是报文主体返回资源对应的URI
。
Content-MD5
首部字段 Content-MD5 是一串由 MD5 算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整
,以及确认传输到达
。
ps:
内容如果能够被篡改,那么同时意味 着 Content-MD5 也可重新计算然后被篡改。所以处在接收阶段的客户端 是无法意识到报文主体以及首部字段 Content-MD5 是已经被篡改过的。
Content-Range
针对范围请求
,返回响应时使用的首部字段 Content-Range,能告知客户端作为响应返回的实体的哪个部分符合范围请求。
Content-Type
说明了实体主体内对象的媒体类型。和首部 字段 Accept 一样,字段值用 type/subtype 形式赋值。 参数 charset 使用 iso-8859-1 或 euc-jp 等字符集进行赋值。
资源时效相关
Expires
将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段 Expires 的响应后,会以缓存来应答请求
。在Expires 字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源
。
ps:当首部字段 Cache-Control 有指定 max-age 指令时,比起首 部字段 Expires,会优先处理 max-age 指令。
Last-Modified
指明资源最终修改的时间。
为Cookie服务的首部字段
Set-Cookie
服务器赋予客户端的Cookie的属性设置:
- NAME=VALUE —— 赋予Cookie名称和值(必需项)
- expires=DATE —— Cookie有效期
- path=PATH —— 将服务器上的文件目录作为Cookie的适用对象
- domain=域名 —— 作为Cookie适用对象的域名
- Secure —— 仅在HTTPS安全通信时才发送Cookie
- HttpOnly —— 加以限制,使Cookie不能被JS脚本访问
Cookie
当客户端想获得 HTTP 状态管理 支持时,就会在请求中包含从服务器接收到的Cookie。
参考资料
《图解HTTP》 by 上野宣