HTTP首部
首部字段结构:
- HTTP报文:点击查看。
- 首部组成:由首部字段名和字段值构成的,中间用冒号“:”分隔。
例:Content- Type: text/html
- 一个首部字段可以有多个字段值。
例:Keep-Alive: timeout=15, max=100
若HTTP首部字段重复了会如何?
这种情况在规范内尚未明确,根据浏览器内部处理逻辑的不同,结果可能并不一致。有些浏览器会优先处理第一次出现的首部字段,而有些则会优先处理最后出现的首部字段。
端到端首部和逐跳首部
HTTP首部字段将定义成缓存代理和非缓存代理的行为,分成2种类型。
- 端到端首部(End-to- end Header):
分在此类别中的首部会转发给请求/响应对应的最终接收目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发。 - 逐跳首部( Hop-by-hop He ader):
分在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再转发。HTTP/1.1 和之后版本中,如果要使用hop-by-hop首部,需提供Connection首部字段。
下面列举了HTTP/1.1中的逐跳首部字段。除这8个首部字段之外,其他所有字段都属于端到端首部。
●Conne ction
●Keep-Alive
●Proxy- Authenticate
●Proxy-. Authorization
●Trailer
●TE
●Transfe r-Encoding
●Upgrade
我的理解 :就是所有的这些HTTP首部字段可以按照缓存首部和不缓存首部分为两种。
逐跳首部就是比如客户端将请求转发给代理服务器,如果这个请求里包含逐跳首部,那么代理服务器在接收到这个请求后会删除这些逐跳首部再将其转发给下一目标。
端到端首部就是在响应经过中间的代理服务器时,代理服务器在生成新的响应返回给客户端的时候(代理服务器会添加一些首部,详见7)会保存这些首部并且将其转发给最终目标。
4种首部字段类型:
HTTP首部字段根据实际用途被分为以下4种类型。
1、通用首部字段( General Header Fields ):
请求报文和响应报文两方都会使用的首部。如下图所示:
Cache-Control:
通过指定首部字段Cache-Control的指令,就能操作缓存的工作机制。
- 指令的参数是可选的,多个指令之间通过“”分隔。首部字段Cache-Control的指令可用于请求和响应。
- 缓存请求指令及参数(字段值):
- 缓存响应指令及参数(字段值):
- no-cache指令(和no-store的区别):
不是不可以进行缓存,只不过使用缓存之前一定要向服务器进行验证,会使用last-Modified和Etag往返浏览器进行对比,判断时间和唯一标识符和服务器的是否一致,一致的话304使用缓存,不一致的话请求服务器。 - no-store:才是真正的不缓存。
- s- maxage指令的功能和max-age指令的相同,max-age数值代表资源保存为缓存的最长时间。
- min-fresh指令要求缓存服务器返回至少还未过指定时间的缓存资源,比如,当指定min-fresh为60秒后,过了60秒的资源都无法作为响应返回了。
- max-stale可指示缓存资源,即使过期也照常接收。如果指令未指定参数值,那么无论经过多久,客户端都会接收响应;如果指令中指定了具体数值,那么即使过期,只要仍处于max-stale指定的时间内,仍旧会被客户端接收。
- 使用only-if-cached指令表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。换言之,该指令要求缓存服务器不重新加载响应,也不会再次确认资源有效性。若发生请求缓存服务器的本地缓存无响应,则返回状态码504 Gateway Timeout。
- 使用must-revalidate指令,代理会向源服务器再次验证即将返回的响应缓存目前是否仍然有效。若代理无法连通源服务器再次获取有效资源的话,缓存必须给客户端。一条 504 ( Gateway Timeout)状态码。另外,使用must-revalidate指令会忽略请求的max-stale 指令(即使已经在首部使用了max-stale, 也不会再有效果)。
- proxy-revalidate指令要求所有的缓存服务器在返回响应之前,必须再次验证缓存的有效性。
- 使用no-transform指令规定无论是在请求还是响应中,缓存都不能改变实体主体的媒体类型。这样做可防止缓存或代理压缩图片等类似操作。
- 通过cache- extension标记(token) ,可以扩展Cache -Control首部字段内的指令。但如果缓存服务器不能理解community这个新指令,就会直接忽略。因此,extension tokens仅对能理解它的缓存服务器来说是有意义的。
connection:
- 控制不再转发给代理的首部字段(逐跳首部)。
- 管理持久连接。
Connection: close
HTTP/1.1版本的默认连接都是持久连接。为此,客户端会在持久连接上连续发送请求。当服务器端想明确断开连接时,则指定Connection首部字段的值为Close。如果想在旧版本的HTTP协议上维持持续连接,则需要指定Connection首部字段的值为Keep-Alive。
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
Trailer:
首部字段Trailer会事先说明在报文主体后记录了哪些首部字段。该首部字段可应用在HTTP/1.1版本分块传输编码时。例如:
Via:
- 使用首部字段Via是为了追踪客户端与服务器之间的请求和响应报文的传输路径。报文经过代理或网关时,会先在首部字段Via中附加该服务器的信息,然后再进行转发。
- Via首部是为了追踪传输路径,所以经常会和TRACE方法一起使用。比如,代理服务器接收到由TRACE方法发送过来的请求(其中Max-Forwards:0)时,代理服务器就不能再转发该请求了。这种情况下,代理服务器会将自身的信息附加到Via首部后,返回该请求的响应。
Warning:
- HTTP/1.1的Warning首部是从HTTP/1.0的响应首部(Retry-After) 演变过来的。该首部通常会告知用户一些与缓存相关的问题的警告。
- Warning首部的格式如下。最后的日期时间部分可省略。
Warning: [警告码][警告的主机:端口号]“[警告内容]”([日期时间])
2、请求首部字段
请求首部字段是从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。P99
-
Accept、Accept-Charset、Accept-Encoding、Accept-Language可用权重q值来表示相对优先级。
-
首部字段Authorization是用来告知服务器,用户代理的认证信息(证书值)。通常,想要通过服务器认证的用户代理会在接收到返回的401状态码响应(即该页面需要HTTP认证)后,把首部字段Authorization加入请求中。共用缓存在接收到含有Authorization 首部字段的请求时的操作处理会略有差异。
例如:Authorization: Basic dWVub3Nlbj pwYXNzd29yZA==
-
虚拟主机运行在同一个IP上,因此使用首部字段Host加以区分。
-
形如If-xx这种样式的请求首部字段,都可称为条件请求。服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
-可以使用星号(*)指定If-Match的字段值。针对这种情况,服务器将会忽略EIag的值,只要资源存在就处理请求。
-首部字段If-Modified-Since,属附带条件之一,它会告知服务器若If-Modified-Since字段值早于资源的更新时间,则希望能处理该请求。而在指定If-Modified-Since字段值的日期时间之后,如果请求的资源都没有过更新,则返回状态码304 Not Modified的响应。
-用于指定If-None Match字段值的实体标记(EIag) 值与请求资源的ETag不一致时,它就告知服务器处理该请求。在GET或HEAD方法中使用首部字段IfNone Match可获取最新的资源。因此,这与使用首部字段If-Modified-Since时有些类似。
-If-Range字段值若是跟ETag值或更新的日期时间匹配一致,那么就作为范围请求处理,若不一致,则忽略范围请求,返回全部资源。 -
Max-F orwards:
通过TRACE方法或OPTIONS方法,发送包含首部字段Max-Forwards的请求时,该字段以十进制整数形式指定可经过的服务器最大数目。服务器在往下一个服务器转发请求之前,Max-Forwards 的值减1后重新赋值。当服务器接收到Max-Forwards值为0的请求时,则不再进行转发,而是直接返回响应。若是转发过程出现错误,根据这个可以知道哪儿出错了。
-
只要查看Referer就能知道请求的URI是从哪个Web页面发起的。例如:
Referer: http:/ /www. hackr. jp/index. htm
-
首部字段User- Agent会将创建请求的浏览器和用户代理名称等信息传达给服务器。由网络爬虫发起请求时,有可能会在字段内添加爬虫作者的电子邮件地址。此外,如果请求经过代理,那么中间也很可能被添加上代理服务器的名称。
3、响应首部字段
从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
- 首部字段Age能告知客户端,源服务器在多久前创建了响应。字段值的单位为秒。若创建该响应的服务器是缓存服务器,Age 值是指缓存后的响应再次发起认证到认证完成的时间值。代理创建响应时必须加上首部字段Age。
- 首部字段ETag能告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的ETag值。资源更新值也更新。该值由服务器分配。
ETag中有强ETag值和弱ETag值之分。强ETag值不论实体发生多么细微的变化都会改变其值。弱ETag值只用于提示资源是否相同,只有资源发生了根本改变,产生差异时才会改变ETag值,这时,会在字段值最开始处附加W/。 - 使用首部字段Location可以将响应接收方引导至某个与请求URI位置不同的资源。基本上,该字段会配合3xx: Redirection 的响应,提供重定向的URI。
- 首部字段Vary可对缓存进行控制。源服务器会向代理服务器传达关于本地缓存使用方法的命令。从代理服务器接收到源服务器返回包含Vary指定项的响应之后,若再要进行缓存,仅对请求中含有相同Vary指定首部字段的请求返回缓存。即使对相同资源发起请求,但由于Vary指定的首部字段不相同,因此必须要从源服务器重新获取资源。
4、实体首部字段
针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。在请求和响应两方的HTTP报文中都含有与实体相关的首部。
- 首部字段Content-MD5是一串由MD5算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。
对报文主体执行MD5算法获得的128位二进制数,由于HTTP首部无法记录二进制值,再通过Base64编码后将结果写入Content-MD5字段值。为确保报文的有效性,作为接收方的客户端会对报文主体再执行一次相同的MD5算法。计算出的值与字段值作比较后,即可判断出报文主体的准确性。
采用这种方法,对内容上的偶发性改变是无从查证的,也无法检测出恶意篡改。其中一个原因在于,内容如果能够被篡改,那么同时意味着Content-MD5也可重新计算然后被篡改。所以处在接收阶段的客户端是无法意识到报文主体以及首部字段Content-MD5是已经被篡改过的。 - 首部字段Expires会将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段Expires的响应后,会以缓存来应答请求,在Expires字段值指定的时间之前,响应的副本会一直被保存。 当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。源服务器不希望缓存服务器对资源缓存时,最好在Expires字段内写入与首部字段Date相同的时间值。但是,当首部字段Cache- Control有指定max-age指令时,比起首部字段Expires,会优先处理max-age指令。
非HTTP/1.1首部字段:
在HTTP协议通信交互中使用到的首部字段,不限于RFC2616中定义的47种首部字段。非正式的首部字段统一归纳在RFC4229 HTTP Header Field Registrations中。如Cookie、Set-Cookie 和Content-Disposition等。