HTTP之首部
HTTP 的首部大致有 5 种:通用首部,请求首部,实体首部,响应首部以及扩展首部。
1. 通用首部
通用头不是应用于请求消息中的特定实体,而是应用于整个请求消息,通常既适用于请求消息,也适用于响应消息。
通用头有 Connection,Connection 中的 "Keep-Alive" 表明了 TCP 连接是一个持续连接。
通用首部是客户端和服务器都可以使用的通用首部。可以在客户端、服务器和其他应用程序之间提供一些非常有用的通用功能。如,Data 首部就是一个通用首部,每一端都可以用它来说明构建报文的时间和日期:
Data: Tue, 3 Oct 1974 02:16:00 GMT
典型的通用首部如下:
- Connection:指示客户端与服务器在进行 HTTP 通信时如何处理 TCP 连接,如果 Connection 的值为 close,则表示本次 HTTP 请求响应后结束 TCP 连接;如果 Connection 的值为 Keep-Alive(HTTP 1.1 下为默认),则表示 TCP 连接一直有效。
- Date:Date 通用头域表明消息产生的日期和具体时间。
- MIME-Version:给出了发送端使用的 MIME 版本。
- Trailer:如果报文采用了分块传输编码(chunked transfer encoding)方式,就可以用这个首部列出位于报文拖挂(trailer)部分的首部集合。
- Transfer-Encoding:指示整个消息主体的传输编码方式,主要是为了实现在接收端和发送端之间进行安全的数据传输。比如
Transfer-Encoding: chunked
表示消息主体采用块编码的方式。 - Update:给出了发送端可能想要 "升级" 使用的新版本或协议。
- Upgrade:客户端可以通过它表示自己希望进行协议转换(比如从 HTTP 一个版本转换到另一个版本),如果服务器同意的话会切换到这个指定的协议,这个协议一般是指应用层协议。
- Via:Via 用来指明请求和响应消息在客户端和服务器之间传递时所经过的代理和网关以及相关的中间协议。比如 HTTP 1.0 的请求消息发送给代理 A,A 使用 HTTP 1.1 将消息转发给网关 B,B 再发送给源服务器,这时源服务器看到 Via 头域为
Via: 1.0 A, 1.1 B
。 - Warning:携带相关警告信息,比如可以被代理和网关用来警告客户端所接收内容的过期状态以及警告客户端实体内容的编码格式发生了变化等。
通用缓存首部
- Cache-Control:用于随报文传送缓存指示。
- Pragma:被用于包含特定执行指令,这些指令可能被应用于请求和响应消息传递过程中的任何接收者。最常用的为
Pragma: no-cache
,表示对请求的实体内容不予缓存。
2. 请求首部
请求头主要包含本请求的附加信息以及客户端的附加信息。 请求首部是请求请求报文特有的。它们为服务器提供了一些额外信息,比如客户端希望接收什么类型的数据。如下面的 Accept 首部就用来告知服务器客户端会接受与其请求类型相符的任意媒体类型:
Accept: */*
典型的请求头如下:
- Accept:用于指定本请求所期望的服务器返回响应的媒体类型。比如
Accept: audio/*; q=0.2, audio/basic
表明用户客户端希望接收到 audio/basic 的媒体,但也可以接受其他任何 audio 类型(audio/* 表示),但偏好程度只有 audio/basic 的 20%(这里的 q 是一个表示喜欢程度的质量参数)。 - Accept-Charset:用来指定客户端能接受什么样的字符集响应。比如
Accept-Charset: iso-8859-5
。 - Accept-Encoding:和 Accept 头相似,但 Accept-Encoding 限定的是客户端可以从服务器接收的内容编码。比如
Accept-Encoding: compress, gzip
。 - Accept-Language:和 Accept 头相似,但 Accept-Language 限定的是客户端可以从服务器接收的自然语言。比如
Accept-Language: en-us
。 - Accept-Range:指示客户端希望从服务器收到的内容的字节范围。
- Authorization:客户端的某些访问要求服务器授权,通常客户端会先在服务器的响应消息中收到包含有授权证书的 WWW-Authenticate 头,然后在需要授权的请求消息里包含一个带有这个授权证书的 Authorization 请求头。
- From:包含客户端当前操作用户的 E-mail 地址,代表的是具体的用户,而不是发出请求的主机。
- Host:指定请求服务器的域名/IP地址和端口号。同一台机器上,可能部署多个app,通过解析host+端口,指定具体访问站点。一个 IP 地址可以对应多个域名:一台虚拟主机(服务器)只有一个 ip,上面可以放成千上万个网站。当对这些网站的请求到来时,服务器根据 Host 这一 行中的值来确定本次请求的是哪个具体的网站。以下为 Host 的要点:
- HTTP/1.0 不带 Host,HTTP/1.1 新增 Host 头
- Host 可以是域名,也可以是 IP,也可以跟端口号
- Host 可以由程序自定义,某些程序为了防止运营商或者绕过防火墙,可以定义虚假 Host
- HTTP/1.1 中的 Host 可以为空值但不可以不带。如果不带 Host 头,会返回 400 Bad request
- 部分站点不校验 Host,可以传任意
- If-Match:与 ETag 一起用来判断已缓存的内容是否被修改过。比如,客户端在获取内容时会获取一个与内容相关的实体标签 ETag(内容变化会使 ETag 变化),下次再请求同样内容时,会在请求头的 If-Match 中包含这个 ETag,然后发给可能存有更新内容的服务器。服务器将收到的 ETag 与本地目前的 ETag 进行比较,如果匹配返回所请求内容。这种方法在断点续传的时候使用较多。
- If-None-Match:与 If-Match 用法类似,结果相反。如果 If-None-Match 中包含了 ETag 的值,服务器在进行比较后发现如果不匹配,则返回所请求的内容,否则不返回相关内容。这种方法在网页刷新的时候使用较多。
- If-Modified-Since:当客户端请求服务器判断自己缓存的内容是否变化时,可以设置 If-Modified-Since 头,如果服务器上的内容修改时间比这个头的时间值还要新,那么将返回新的内容,否则不返回。这个与 If-Unmodified-Since 类似,是用来判断资源变化的另一种方式。
- If-Unmodified-Since:与 If-Modified-Since 正好相反,如果服务器上的内容修改时间比这个头时间的值还要新,则不返回新的内容,否则返回所请求内容。
- If-Range:一般结合 Range 头一起使用。If-Range 的值可以是 ETag,也可以是具体的时间值。如果收到含有 If-Range 头的服务器发现所请求内容没有改变,则根据 Range 头指示的字节范围进行续传,否则返回整个文档内容。
- Max-Forwards:指示此 HTTP 请求可以途径的代理服务器或网关个数。每经过一个代理服务器或网关,这个值就会被减 1。如果减到 0,则代理服务器或网关将中止继续发送。
- Proxy-Authorization:与 Authorization 类似,只不过是需要代理服务器进行授权时才使用。
- Range:客户端通知服务器只需返回部分内容,以及部分内容的范围。这对于较大文档的断电续传是很有帮助的。如果客户机在一次请求中,只收到了服务器返回的部分内容,则客户端可以再发出一个带 Range 头的请求,这时服务器将会返回 Range 头值规定的那部分内容。
- Referer:告诉服务器这次请求是通过点击哪个网页上的超链接转向过来的。由于可以使用 Telnet 来仿造 HTTP 请求,所以 Referer 是不可靠的。"Referer" 是由于 HTTP 的作者拼写错误,在实际应用中沿袭下来,不可以写成正确的拼写方式 Referrer。
- User-Agent:即用户代理,用于指定浏览器的类型和名字,比如 Mozilla/4.0。是一种向访问网站提供所使用的浏览器类型及版本、操作系统及版本、浏览器内核等信息的标识。通过这个标识,用户所访问的网站可以显示不同的排版从而为用户提供更好的体验或者进行信息统计;例如用手机访问谷歌和电脑访问是不一样的,这些是谷歌根据访问者的 User-Agent 来判断的。User-Agent可以进行伪装。
请求的信息性首部
- Client-IP:提供了运行客户端的机器的 IP 地址。
- From:提供了客户端用户的 E-mail 地址。
- Host:给出了接收请求的服务器的主机名和端口号。
- Referer:提供了包含当前请求 URI 的文档的 URL。
- UA-Color:提供了与客户端显示器的显示颜色有关的信息。
- UA-CPU:给出了客户端 CPU 的类型或制造商。
- UA-Disp:提供了与客户端显示(屏幕)能力有关的信息。
- UA-OS:给出了运行在客户端机器上的操作系统名称及版本。
- UA-Pixels:提供了客户端显示器的像素信息。
- User-Agent:将发起请求的应用程序名称告知服务器。
Accept 首部
- Accept:告诉服务器能够发送哪些媒体类型。
- Accept-Charset:告诉服务器能够发送哪些字符集。
- Accept-Encoding:告诉服务器能够发送哪些编码方式。
- Accept-Language:告诉服务器能够发送哪些语言。
- TE:告诉服务器可以使用哪些扩展传输编码。
条件请求首部
有时客户端希望为请求加上某些限制。通过条件请求首部,客户端就可以为请求加上这种限制,要求服务器在对请求进行响应之前,确保某个条件为真。
- Expect:允许客户端列出某请求所要求的服务器行为。
- If-Match:如果实体标记与文档当前的实体标记相匹配,就获取这份文档。
- If-Modified-Since:除非在某个指定的日期之后资源被修改过,否则就限制这个请求。
- If-None-Match:如果提供的实体标记与当前文档的实体标记不相符,就获取文档。
- If-Range:允许对文档的某个范围进行条件请求。
- If-Unmodified-Since:除非在某个指定日期之后资源没有被修改过,否则就限制这个请求。
- Range:如果服务器支持范围请求,就请求资源的指定范围。
安全请求首部
- Authorization:包含了客户端提供给服务器,以便其对自身进行认证的数据。
- Cookie:客户端用它向服务器传送一个令牌--它并不是真正的安全首部,但确实隐含了安全功能。
- Cookie2:用来说明请求端支持的 cookie 版本。
代理请求首部
- Max-Forward:在通往源端服务器的路径上,将请求转发给其他代理或网关的最大次数--与 TRACE 方法一同使用。
- Proxy-Authorization:与 Authorization 首部相同,但这个首部是在与代理进行认证时使用的。
- Proxy-Connection:与 Connection 首部相同,但这个首部是在与代理建立连接时使用的。
3. 响应首部
响应报文有自己的首部集,以便为客户端提供信息(比如,客户端在与哪种类型的服务器进行交互)。如,下列 Server 首部就用来告知客户端它在与一个版本 1.0 的 Tiki-Hut 服务器进行交互:
Server: Tiki-Hut/1.0
常用的响应首部如下:
- Age:当服务器使用缓存的内容去响应请求时,用该头部表明该内容从产生到现在经过多长时间。
- Public:服务器为其资源支持的请求方法列表。
- ETag:对应实体内容的一个实体标签,与实体内容紧密相关,实体内容发生任何变化都会使这个头的值发生变化。
- Retry-After:可以与 503 (服务不可用)响应一起使用,服务器用它来告知请求端服务不可用的时长。也可与 3xx(重定向)响应一起使用,服务器用它来告知客户端发送重定向请求之前需要等待的最小时长,比如
Retry-After: 60
。 - Server:包含了源服务器处理请求的软件信息,比如
Server: Apache
。 - Title:对 HTML 文档来说,就是 HTML 文档的源端给出的标题。
- Warning:比原因短语中更详细一些的警告报文。
协商首部
- Accept-Range:指明服务器对用户请求范围的接受程度。比如
Accept-Range: 100-599
。表示服务器只接受请求范围的第 100 字节到 599 个字节。 - Vary:指定了一些请求头,这些请求头可被服务器用来决定缓存的没有过期的内容能否被允许去响应后续相同的请求,比如请求消息发送到代理服务器,其中 Accept-Encoding 头是 "gzip",代理服务器向源服务器转发请求,源服务器给代理服务器返回响应消息,其中 Vary 头为
Vary: Accept-Encoding
,此时代理服务器将响应内容与 gzip 一起缓存。如果后续用户再向代理服务器发送请求时,并且 Accept-Encoding 头的值是 gzip,代理服务器则可以直接使用未过期的缓存内容来响应,如果 Accept-Encoding 头的值是 deflate 或者其他,则需要重新从源服务器获取。
安全响应首部
- Proxy-Authenticate:此头必须被包含在 407 响应(代理认证)里。此头域值由一个 challenge 和 parameters 组成,chanllenge 指明了认证机制,而 parameters 是一些与此代理相关的参数。
- Set-Cookie:不是真正的安全首部,但隐含有安全功能;可以在客户端设置一个令牌,以便服务器对客户端进行标识。
- Set-Cookie2:与 Set-Cookie 类似,RFC 2965 Cookie 定义。
- WWW-Authenticate:必须包含在 401(没有被认证)响应消息中,这个响应头应至少包含一个 challenge 值来标识认证方案以及一些与所请求的 URI 相关的参数。
4. 实体首部
实体首部指的是用于应对实体主体部分的首部。比如,可以用实体首部来说明实体主体部分的数据类型。如通过下列 Content-Type 首部告知应用程序,数据是以 iso-Iatin-1 字符集表示的 HTML 文档:
Content-Type: text/html; charset=iso-latin-1
典型的实体首部如下:
- Allow:指示可以使用的请求方式。比如
Allow: GET, HEAD, PUT
。 - Location:当客户端向服务器请求一个内容,但请求消息中 URI 所标识的内容发生了转移,那么接收者能将访问重定向于 Location 指示的 URI,如
Location: http://www.netitv.com/netitv/movie_1.shtml
。
内容首部
- Content-Base:解析主体中的相对 URL 时使用的基础 URL。
- Content-Encoding:指示实体内容以哪种方式编码。比如
Content-Encoding: gzip
。 - Content-Language:实体内容的国家语言,比如
Content-Language: zh-ch
表示简体中文。 - Content-Length:实体内容的大小,比如
Content-Length: 3495
。 - Content-Location:当实体内容的真正 URI 和请求 URI 不同时,在消息里提供这个真正的位置信息。
- Content-MD5:实体内容的 MD5 摘要算法 Base-64 值,以提供实体内容的完整性校验。服务器可以通过对实体内容进行 MD5 摘要算法与此头的值是否相同来确定接收的请求是否没有错误与改变。
- Content-Range:表示返回的内容是整个实体内容的哪个部分。比如
Content-Range: 2351-4767/8568
,表明本次响应是实体内容的第 2351 字节到第 4767 字节,8565 是实体内容的总大小。 - Content-Type:服务器在返回内容时需要告诉浏览器本响应的内容是什么类型的。HTTP 中把这种不同媒体类型的格式称为多媒体文件格式(MIME),而本实体头指出所传输实体内容的 MIME。由于 Web 服务器不知道所返回的内容文件是哪种 MIME,所以需要通过对 Web 服务器进行设置,使文件扩展名与 MIME 之间进行映射。比如
Content-Type: text/html; charset=ISO-8859-4
。
实体缓存首部
- ETag:与此实体相关的的实体标记。
- Expires:指示当前内容在何时之后被认为过期,缓存在为客户端请求提供服务时,如果缓存内容已经过期,则不会使用此缓存内容来直接提供服务。比如
Expires: Tue. 17 Jul 2011 18:06:45 GMT
。 - Last-Modified:指定所访问内容的最后更新时间。
5. 扩展首部
扩展首部是非标准的首部,由应用程序开发者创建,但还未添加到已批准的 HTTP 规范中去。即使不知道这些扩展首部的含义,HTTP 程序也要接受它们并对其进行转发。