HTTP 首部字段:即请求头和响应头中的信息,是由首部字段名和字段值构成的。使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。
客户端可以设置请求头信息,获取响应头信息;服务器端可以设置响应头信息,获取请求头信息。
HTTP/1.1 规范定义了 47 种首部字段,根据实际用途被分为以下 4 种类型:通用首部字段、请求首部字段、响应首部字段、实体首部字段;还有一些 Cookie、Set-Cookie 等在其他协议中定义的首部字段,使用频率也很高;除此之外,HTTP 首部字段还是可以自行扩展。
单个 HTTP 首部字段可以对应多个字段值(例如
Keep-Alive: timeout=15,max=100
)。
当 HTTP 报文首部中出现了两个或两个以上相同的首部字段名时,这种情况在规范内尚未明确,根据浏览器内部处理逻辑的不同,结果可能并不一致,有些浏览器会优先处理第一次出现的首部字段,而有些则会优先处理最后出现的首部字段。
通用首部字段:
通用首部字段是指请求报文和响应报文双方都会使用的首部,共有 9 种。
Cache-control
:
Cache-control
:用来控制缓存。
指令可以按请求和响应分为缓存请求指令和缓存响应指令,多个指令之间通过 ,
分割。
- 缓存请求指令有:
no-cache
、no-store
、max-age
、max-stale
、min-fresh
、no-transform
、only-if-cached
、cache-extension
。 - 缓存响应指令有:
public
、private
、no-cache
、no-store
、no-transform
、must-revalidate
、proxy-revalidate
、max-age
、s-maxage
、cache-extension
。
其中,no-cache
表示缓存前必须先确认其有效性;no-store
表示不缓存任何内容;max-age
表示缓存最大的有效期。
Connection:
Connection 首部字段具备两个作用:
- 控制不再转发给代理的首部字段。
- 管理持久连接。
HTTP/1.1 版本的默认连接都是持久连接。为此,客户端会在持久连接上连续发送请求。当服务器端想明确断开连接时,则指定 Connection 首部字段的值为 Close。
HTTP/1.1 之前的 HTTP 版本的默认连接都是非持久连接。为此,如果想在旧版本的 HTTP 协议上维持持续连接,则需要指定 Connection 首部字段的值为 Keep-Alive。
Date:
Date 表明创建 HTTP 报文的日期和时间。
Pragma:
Pragma 只用在客户端发送的请求中,客户端会要求所有的中间服务器不返回缓存的资源。Pragma 是 HTTP/1.1 之前版本的历史遗留字段,唯一形式是 Pragma: no-cache
。
所有的中间服务器如果都能以 HTTP/1.1 为基准,那直接采用 Cache- Control: no-cache 指定缓存的处理方式是最为理想的。但要整体掌握全部中间服务器使用的 HTTP 协议版本却是不现实的。因此,发送的请求会同时含有下面两个首部字段:
Cache-Control: no-cache Pragma: no-cache
Trailer:
Trailer 会事先说明在报文主体的最后记录了哪些首部字段。
Transfer-Encoding:
Transfer-Encoding 规定了传输报文主体时采用的编码方式。
Upgrade:
Upgrade:用于检测 HTTP 协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。
对于附有首部字段 Upgrade 的请求,服务器可用 101 Switching Protocols 状态码作为响应返回。
Via:
Via:为了追踪客户端与服务器之间的请求和响应报文的传输路径,报文经过代理或网关时,会先在首部字段 Via 中附加该服务器的信息,然后再进行转发。
Via 首部是为了追踪传输路径,所以经常会和 TRACE 方法一起使用。
比如,代理服务器接收到由 TRACE 方法发送过来的请求,其中 Max-Forwards:0 时,代理服务器就不会在转发该请求了,这种情况下,代理服务器会将自身的信息附加到 Via 首部后,返回该请求的响应。
Warning:
该首部通常会告知用户一些与缓存相关的问题的警告。Warning 首部的格式如下:Warning: [警告码][警告的主机:端口号]“[警告内容]”([日期时间])
,最后的日期时间部分可省略。
Warning: 113 gw.hackr.jp:8080 "Heuristic expiration" Tue, 03 Jul 2012 05:09:44 GMT
请求首部字段:
请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容,共有19 种。
Accept:
Accept:告知服务器,客户端接收的数据类型。
Accept-Charset:
Accept-Charset 可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。可一次性指定多种字符集。可用权重 q 值来表示相对优先级。
Accept-Encoding
:
Accept-Encoding
:告知服务器,客户端支持的文件的压缩格式。
浏览器在接收到压缩文件之后,会自动解压并执行。
Accept-Language:
Accept-Language 用来告知服务器用户代理能够处理的语言类型,以及语言类型的相对优先级。可一次指定多种语言类型,按权重值 q 来表示相对优先级。
TE:
首部字段 TE 会告知服务器客户端能够处理响应的传输编码方式及相对优先级。
TE 和首部字段 Accept-Encoding 的功能很相像,但是用于传输编码。
TE: gzip, deflate;q=0.5
Expect:
Expect:告知服务器,客户端期望出现的某种特定行为。
因服务器无法理解客户端的期望作出回应而发生错误时,会返回状态码 417 Expectation Failed。
Authorization:
Authorization:用来告知服务器用户代理的认证信息。
通常,想要通过服务器认证的用户代理会在接收到返回的 401 状态码响应后,把首部字段 Authorization 加入请求中。
Proxy-Authorization:
接收到从代理服务器发来的认证质询时,客户端会发送包含首部字段 Proxy-Authorization 的请求,以告知服务器认证所需要的信息。
客户端与服务器之间的认证,使用首部字段 Authorization。
客户端与代理之间的认证,使用首部字段 Proxy-Authorization。
Referer:
Referer 会告知服务器请求的原始 URI。
From:
From 用来告知服务器使用用户代理的用户的电子邮件地址。
User-Agent
:
User-Agent
:会将创建请求的浏览器和用户代理名称等信息传给服务器。
由网络爬虫发起请求时,有可能会在字段内添加爬虫作者的电子邮件地址。
如果请求经过代理,那么中间也很可能被添加上代理服务器的名称。
Host:
首部字段 Host 会告知服务器,请求的资源所处的互联网主机名和端口号。
Host 首部字段在 HTTP/1.1 规范内是唯一一个必须被包含在请求内的首部字段。
首部字段 Host 和以单台服务器分配多个域名的虚拟主机的工作机制有很密切的关联,虚拟主机运行在同一个 IP 上,因此使用首部字段 Host 加以区分。
Max-Forwards:
通过 TRACE 方法或 OPTIONS 方法,发送包含首部字段 Max- Forwards 的请求时,该字段以十进制整数形式指定可经过的服务器最大数目。服务器在往下一个服务器转发请求之前,Max-Forwards 的值减 1 后重新赋值。当服务器接收到 Max-Forwards 值为 0 的请求时,则不再进行转发,而是直接返回响应。
If-Match
:
If-Match
:告知服务器匹配资源所用的实体标记 ETag 值。服务器会比对 If-Match
的字段值和资源的 ETag 值,仅当两者一致时,才会执行请求;反之,则返回状态码 412 Precondition Failed 的响应。
形如 If-xxx 这种样式的请求首部字段,都可称为条件请求。服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
If-None-Match
:
If-None-Match
:和 if-Match
作用相反。当 If-None-Match 字段值与请求资源的 ETag 不一致时,它就告知服务器处理该请求。
If-Modified-Since
:
If-Modified-Since
:告知服务器如果在 If-Modified-Since
字段指定的日期时间后,服务器上的资源发生了更新,服务器会接受请求;反之,返回状态码 304 Not Modified 的响应。
If-Unmodified-Since
:
If-Unmodified-Since
: 和 If-Modified-Since
的作用相反。它的作用的是告知服务器,指定的请求资源只有在字段值内指定的日期时间之后,未发生更新的情况下,才能处理请求;如果在指定日期时间后发生了更新,则以状态码 412 Precondition Failed 作为响应返回。
If-Range
:
If-Range
:告知服务器若指定的 If- Range
字段值(ETag 值或者时间)和请求资源的 ETag 值或时间相一致时,则作为范围请求处理;反之,则返回全体资源。
Range:
Range:告知服务器,只需获取部分资源的范围。接收到附带 Range 首部字段请求的服务器,会在处理请求之后返回状态码为 206 Partial Content 的响应;无法处理该范围请求时,则会返 回状态码 200 OK 的响应及全部资源。
Range: bytes=5001-10000 // 请求获取从第 5001 字节至第 10000 字节的资源
响应首部字段:
响应首部字段是由服务器端向客户端返回响应报文中所使用的字段,用于补充响应的附加信息、服务器信息,以及对客户端的附加要求等信息,共有 9 种。
Accept-Ranges:
Accept-Ranges 是用来告知客户端服务器是否能处理范围请求。可指定的字段值有两种,可处理范围请求时指定其为 bytes,反之则指定其为 none。
Age:
Age 能告知客户端,源服务器在多久前创建了响应。字段值的单位为秒。
若创建该响应的服务器是缓存服务器,Age 值是指缓存后的响应再次 发起认证到认证完成的时间值。
缓存服务器创建响应时必须加上首部字段 Age。
ETag: ETag 能告知客户端实体标识。
服务器会为每份资源分配对应的 ETag 值,以字符串形式做唯一性标识。生成 ETag 值时,并没有 统一的算法规则,而仅仅是由服务器来分配;当资源更新时,ETag 值也需要更新。
ETag 中有强 ETag 值和弱 ETag 值之分。
- 强 ETag 值,不论实体发生多么细微的变化都会改变其值,例如
ETag: "usagi-1234"
。- 弱 ETag 值只用于提示资源是否相同。只有资源发生了根本改变,产生差异时才会改变 ETag 值。这时,会在字段值最开始处附加
W/
,例如ETag: W/"usagi-1234"
。
Location:
Location 可以将响应接收方引导至某个与请求 URI 位置 不同的资源。基本上,该字段会配合 3xx :Redirection 的响应,提供重定向的 URI。
WWW-Authenticate:
WWW-Authenticate 用于 HTTP 访问认证。它会告知客户端访问指定资源的认证方案和带参数提示的质询。
状态码 401 Unauthorized 响应中, 肯定带有首部字段 WWW-Authenticate。
Proxy-Authenticate:
Proxy-Authenticate 会把由代理服务器所要求的认证信息发送给客户端。
Retry-After:
Retry-After 告知客户端应该在多久之后再次发送请求。字段值可以指定为具体的日期时间,也可以是创建响应后的秒数。主要配合状态码 503 Service Unavailable 响应,或 3xx Redirect 响应一起使用。
Server:
Server 告知客户端当前服务器上安装的 HTTP 服务器应用程序的信息。
Vary:
用于代理服务器实现缓存服务。
不同客户端对内容格式的支持程度不同,所以即便请求 URI 和请求方法都相同,服务器返回的数据也会不同。Vary 字段记录了代理服务器返回特定数据参考了哪些请求字段。
代理服务器拿到源服务器的响应报文,会根据 Vary 里的字段列表,缓存不同版本的数据;当客户端再次访问时 ,代理服务器会分析请求字段,来决定是直接从缓存返回响应还是先从源服务器端获取资源后才能作为响应返回。
客户端请求 /sample.html
资源,且希望获取到的资源是英文类型;请求来到了代理服务器,但是里面没有缓存,于是代理服务器把请求发送了给源服务器;源服务器拿到了请求报文分析了一波,决定了返回哪个资源,但是,源服务器还希望介于它和客户端之间的代理服务器也可以根据 Accept-Language
返回正确的数据,于是在响应头中加上了 Vary: Accept-Language
,并返回了指定的资源给代理服务器;资源来到了代理服务器,发现了响应头中有 Vary: Accept-Language
,于是不仅缓存了源服务器返回的资源,并保存了Accept-Language
和当前资源的映射关系,然后把资源返回给了客户端;下次,客户端又发送了相同的请求,代理服务器接收到了请求,缓存命中了此资源,于是此资源被直接返回给了客户端。
实体首部字段:
实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息,共有 10 种。
HTTP 实体指的是 HTTP 请求和响应中携带的数据部分,也就是请求体和响应体。
Allow:
Allow 用于通知客户端,服务器能够支持请求 URI 的所有 HTTP 方法。
当服务器接收到不支持的 HTTP 方法时,会以状态码 405 Method Not Allowed 作为响应返回。与此同时,还会把所有能支持的 HTTP 方法写入首部字段 Allow 后返回。
Content-Encoding:
Content-Encoding 会告知客户端,服务器对实体的主体部分选用的内容编码方式。
内容编码是指在不丢失实体信息的前提下所进行的压缩。主要采用以下 4 种内容编码的方式:gzip、compress、deflate、identity。
Content-Language:
Content-Language 会告知客户端,实体主体使用的自然语言。
Content-Length:
Content-Length :实体主体部分的大小,单位是字节。
Content-Location:
Content-Location 表示的是报文主体返回的资源对应的URI。
当返回的页面内容与实际请求的资源不同时,首部字段 Content-Location 内会写明返回的资源的 URI。例如:访问 http://www.hackr.jp/ 返回的对象却是 http://www.hackr.jp/index-ja.html 等类似情况
Content-MD5:
Content-MD5 的值是一串由 MD5 算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。
对报文主题执行 MD5 算法获得 128 位的二进制数,再通过 Base64 编码后将结果写入 Content-MD5 字段值。为确保报文的有效性,作为接收方的客户端会对报文主体再执行一次相同的 MD5 算法,计算出的值与字段值作比较后,即可判断出报文主体的准确性。
由于 HTTP 首部无法记录二进制值,所以要通过 Base64 编码处理。
采用这种方法,对内容上的偶发性改变是无从查证的,也无法检测出恶意篡改。其中一个原因在于,内容如果能够被篡改,那么同时意味着 Content-MD5 也可重新计算然后被篡改。所以处在接收阶段的客户端是无法意识到报文主体以及首部字段 Content-MD5 是已经被篡改过 的。
Content-Range:
针对范围请求,返回响应时使用的首部字段 Content-Range,能告知客户端作为响应返回的实体的哪个部分符合范围请求。字段值以字节为单位,表示当前发送部分及整个实体大小。
Content-Type
:
Content-Type:发送的数据类型。
属性值有:
application/x-www-form-urlencoded
:表示数据被编码成以=
分割键和值,以&
分割的键值对的形式。name=Lee&age=18
application/json
:表示是 json 类型。{ "name": "Lee", "age": 18 }
text/plain
:表示是文本类型。application/xml
:表示是 xml 类型。<xml> <name>Lee</name> <age>18</age> </xml>
multipart/form-data
:表示是上传文件。
Expires:
Expires 会将资源失效的日期告知客户端。
Last-Modified:
Last-Modified 指明资源的最后修改时间。
为 Cookie 服务的首部字段:
管理服务器与客户端之间状态的 Cookie,虽然没有被编入标准化 HTTP/1.1 的RFC2616 中,但在 Web 网站方面得到了广泛的应用。
Cookie 的工作机制是用户识别及状态管理。Web 网站为了管理用户的状态,会通过 Web 浏览器把一些数据临时写入用户的计算机内;接着,当用户访问该 Web 网站时,可通过通信方式取回之前发放的 Cookie。
调用 Cookie 时,由于可校验 Cookie 的有效期以及发送方的域、路径、协议等信息,所以正规发布的 Cookie 内的数据不会因来自其他 Web 站点和攻击者的攻击而泄漏。
Set-Cookie:
响应首部字段。当服务器准备开始管理客户端的状态时,会事先告知各种信息。
Set-Cookie 的字段值:
- expires 属性:指定浏览器可发送 Cookie 的有效期。若不明确指定则默认为浏览器关闭前为止。
- path 属性:可用于限制指定 Cookie 的发送范围的文件目录。若不指定则默认为文档所在的文件目录。
- domain 属性:指定的域名可做到与结尾匹配一致。若不指定则默认为创建 Cookie 的服务器的域名。
例如:当指定 domain = example.com 时,除 example.com 以外,www.example.com 或者 www2.example.com 等都可以发送 Cookie。
因此,除了针对具体指定的多个域名发送 Cookie 之外,不指定 damain 属性显得更安全。 - secure 属性:用于限制 Web 页面仅在 HTTPS 安全连接时,才可以发送 Cookie。
- HttpOnly 属性:是 Cookie 的扩展功能,它使 JavaScript 脚本无法获得 Cookie,其主要目的是为防止跨站脚本攻击对 Cookie 的信息窃取。
Cookie:
请求首部字段。Cookie 会告知服务器,当客户端想获得 HTTP 状态管理支持时,就会在请求中包含从服务器接收到的 Cookie。
其他首部字段:
HTTP 首部字段是可以自行扩展的,所以在 Web 服务器和浏览器的应用上,会出现各种非标准的首部字段。