1.HTTP报文首部
- HTTP协议的请求和响应报文中必定包含HTTP首部。首部内容为客户端和服务器分别处理请求和响应提供所需要的信息。对于客户端用户来说,这些信息中的大部分内容都无需亲自查看。
- 报文首部由几个字段构成。
- HTTP请求报文:
在请求中,HTTP报文由方法、URI、HTTP版本、HTTP首部字段等部分构成。 - HTTP响应报文:
在响应中,HTTP报文由HTTP版本、状态码(数字和原因短语)、HTTP首部字段3部分构成。 - 在报文众多的字段当中,HTTP首部字段包含的信息最为丰富。首部字段同时存在于请求和响应报文内,并涵盖HTTP报文相关的内容信息。
2.HTTP首部字段
-
使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。
-
HTTP首部字段是由首部字段名和字段值构成的,中间用:分割
-
字段值对应单个HTTP首部字段可以有多个值,如Keep-Alive:timeout=15,max=100
-
HTTP首部字段重复了会如何?
答:这种情况在规范内尚未明确,根据浏览器内部处理逻辑的不同,结果可能并不一致。有些浏览器会优先处理第一次出现的首部字段,而有些则会优先处理最后出现的首部字段。 -
4种HTTP首部字段类型:
通用首部字段:请求和响应报文两方都会使用的首部
请求首部字段:从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
响应首部字段:从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。
实体首部字段:针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。 -
除了上述的47种首部字段,还有Cookie、Set-Cookie和Content-Disposition使用频率也很高
-
HTTP首部字段将定义成缓存代理和非缓存代理的行为,分为2种。
端对端首部:分在此类别中的首部会转发给请求/响应对应的最终接受目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发。
逐跳首部:分在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再转发。在HTTP1.1和之后版本中,如果要使用此首部,需提供Connection首部字段。
3.HTTP/1.1 通用首部字段
-
Cache-Control:
通过制定首部字段Cache-Control的指令,就能操作缓存的工作机制。
指令的参数是可选的,多个指令之间通过’,'分隔,该指令可用于请求及响应时。
如Cache-Control:private,max-age=0,no-cache当制定使用public指令时,则明确表明其他用户也可利用缓存。
当指定private指令后,响应只以特定的用户作为对象。
1.no-cache:
使用该指令的目的是为了防止从缓存中返回过期的资源。
客户端发送的请求中如果包含no-cache指令,则表示客户端将不会接收缓存过的响应。于是,缓存服务器必须把客户端请求转发给源服务器。
如果服务器返回的响应中包含no-cache指令,那么缓存服务器不能对资源进行缓存。源服务器以后也将不再对缓存服务器请求中提出的资源有效性进行确认,且禁止其对响应资源进行缓存。
Cache-Control:no-cache=Location:只能再响应指令中指定该参数,客户端在接收到这个被指定参数值首部字段对应的响应报文后,就不能使用缓存。
2.no-store: 暗示请求或响应中包含机密信息。
PS:从字面意思上很容易把no-cache误解为不缓存,但事实上代表不缓存过期的资源,缓存会向源服务器进行有效期确认后处理资源。no-store才是真正地不进行缓存。
3.s-maxage:指定缓存期限和认证的指令
功能与max-age指令相同。而s-maxage只适用于供多位用户使用的公共缓存服务器(代理)。对于向统一用户重复返回响应的服务器来说,这个指令没有任何作用。
另外,使用该指令后,则直接忽略对Expires首部字段及max-age指令的处理。
4.max-age:
如果判定缓存资源的缓存时间数值比指定时间的数值更小,那么客户端就接收缓存的资源。另外,当指定max-age值为0,那么缓存服务器通常需要将请求转发给源服务器。
当服务器返回的响应中包含该指令时,缓存服务器将不对资源的有效性再作确认。
PS:HTTP1.1会优先处理max-age指令,而忽略掉Expires首部字段。而HTTP1.0则相反。
5.min-fresh:
要求缓存服务器返回至少还未过指定时间的缓存资源。
比如,当指定min-fresh为60秒后,过了60秒的资源都无法作为响应返回了
6.max-stale:
使用该指令可指示缓存资源,即使过期也照常接收。
如果指令为指定参数值,那么无论经过多久,客户端都会接收响应。
如果指令了具体数值,那么即使过期,只要仍处于max-stale指定的时间内,仍旧会被客户端接收。
7.only-if-cached:
表示客户端仅在缓存服务器本地缓存目标资源的情况下才会要求其返回。该指令要求缓存服务器不重新加载响应,也不会再次确认资源有效性。若发生本地缓存无响应,则返回504 Gateway Timeout
8.must-revalidate
代理会向源服务器再次验证即将返回的响应缓存目前是否仍然有效
若代理无法连通源服务器再次获取有效资源的话,缓存必须给客户端一条504状态码
PS:使用了该指令会忽略请求的max-stale指令
9.proxy-revalidate:
要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证有效性
10.no-transform
无论是在请求还是响应中,缓存都不能改变实体主体的媒体类型,防止缓存或代理压缩图片
11.cache-extension token
通过cache-extensions标记,可以扩展Cache-Control首部字段内的指令 -
Connection
1.具备2个作用:控制不再转发给代理的首部字段,管理持久连接
控制不再转发给代理的首部字段:Connection:不再转发的首部字段名
在客户端发送请求和服务器返回响应内,可控制不再转发给代理的首部字段(即逐跳首部)
管理持久连接:HTTP1.1版本的默认链接都是持久连接。当服务器端想明确断开连接时,会指定 Connection首部字段的值为Close。 HTTP1.1之前的HTTP版本的默认链接都是非持久连接,如 果想维持持续连接,则需要指定Connection首部字段的值为Keep-Alive -
Date
1.首部字段Date表明创建HTTP报文的日期和时间。 -
Pragma
1.是HTTP1.1之前版本的历史遗留字段。属于通用首部字段,但只用在客户端发送的请求中,要求所有的中间服务器不返回缓存的资源。
2.所有的中间服务器如果都能以 HTTP/1.1 为基准,那直接采用 Cache-Control: no-cache 指定缓的处理方式是最为理想的。但要整体掌握全部中间服务器使用的 HTTP 协议版本却是不现实的。因此,发送的请求会同时含有下面两个首部字段。 -
Trailer(追踪):
会事先说明在报文主体后记录了哪些首部字段,可应用于分块传输编码时。 -
Transfer-Encoding
规定了传输报文主体时采用的编码方式。HTTP1.1的传输编码仅对分块传输编码有效。 -
Upgrade:
用于检测HTTP协议及其其他协议是否可使用更高的版本进行通信。
对于附有首部字段Upgrade的请求,服务器可用101 Switching Protocols状态码作为响应返回。 -
Via
为了追踪客户端与服务器之间的请求和响应报文的传输路径。
报文经过代理或网关时,会先在首部字段Via中附加该服务器的信息,然后再进行转发,这和traceroute和Received首部的工作机制很类似。
首部字段Via不仅用于追踪报文的转发,还可避免请求回环的发生。所以必须在经过代理时附加。
Via首部是为了追踪传输路径,所以经常会和TRACE方法一起使用。比如,代理服务器接收到由TRACE方法发送过来的请求(其中Max-Forwards:0)时,代理服务器就不能再转发该请求了。这种情况下,代理服务器会将自身的信息附加到Via首部后,返回该请求的响应。 -
Warning
通常会告知用户一些与缓存相关的问题的警告
4.请求首部字段
- Accept:
可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。可使用type/subtype,一次指定多种媒体类型。可用权重q值来表示相对优先级。 - Accept-Charset:
用来通知服务器支持的字符集及字符集的相对优先顺序,可一次性指定多种。可用权重q值来表示相对优先级。 该首部字段应用于内容协商机制的服务器驱动协商。 - Accept-Encoding:
用来告知支持的内容编码即内容编码的优先级顺序。*表示任意的编码格式。 - Accept-Language:
用来告知能够处理的自然语言集以及相对优先级。 - Authorization:
告知服务器,用户代理的认证信息。 - Expect:
期望出现的某种特定行为,因服务器无法理解客户端的期望作出回应而发生错误时,会返回417 Expectation Failed。 目前只定义了100-continue。 - From:
告知用户的电子邮件地址。 - Host:
告知请求的资源所处的互联网主机名和端口号。是唯一一个必须被包含在请求内的首部字段。
请求被发送至服务器时,请求中的主机名会用IP地址直接替换解决。但如果这时,相同的IP地址下部署运行着多个域名,那么就需要使用首部字段Host来明确指出请求的主机名。若服务器未设定主机名,那直接发送一个空值即可。 - If-Match:
1.形如IF-xxx这种样式的请求首部字段,都可称为条件请求。服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
2.服务器会比对If-Match的字段值和资源的ETag值,仅当两者一致时,才会执行请求。反之,返回412 Precondition Failed。 - If-Modified-Since:
会告知服务器如果该字段值早于资源的更新时间,则希望能处理该请求。而反之,返回304 Not Modified。 - If-None-Match:
与IF-Match相反。 - If-Range:
它告知服务器若指定的Range字段值和请求资源的Etag值或时间相一致时,则作为范围请求处理,反之,则返回全体资源。
与If-Match相比,可以少花一半的时间。因为它不匹配会直接返回全部资源。而If-Match则会先返回412 precondition Failed,之后再次请求。 - If-Unmodified-Since:与If-Modified-Since相反。
- Max-Forwards:
服务器在往下一个服务器转发请求之前,该值减1。当服务器收到该值为0的请求时,将不再进行转发,而是直接返回响应。 - Proxy-Authorization:
接收到从代理服务器发来的认证质询时,客户端会发送包含首部字段Proxy-Authorization的请求,以告知服务器认证所需要的信息。该认证行为发生在客户端和代理之间。客户端与服务器之间的认证,使用首部字段Authorization可起到相同作用。 - Range:
对于只需获取部分资源的范围请求,包含首部字段Range即可告知服务器资源的指定范围。
处理请求之后返回状态码206 Partial Content,无法处理时,则会返回200 OK以及全部资源。 - Referer:
告知服务器请求的原始资源的URI。
原始的URI中的查询字符串可能含有ID和密码等保密信息,要是写进Referer转发,有可能导致泄露 - TE:
告知能够处理的响应的传输编码方式,和Accept-Encoding的功能很像,但是属于逐跳首部。
还可以指定伴随trailer字段的分块传输编码的方式,如TE:trailers。 - User-Agent:
创建请求的浏览器和用户代理名称等信息传达给服务器。
5.响应首部字段
- Accept-Ranges:
可处理范围请求时指定其为bytes,反之则指定其为none。 - Age:
告知客户端,源服务器在多久前创建了响应。
若创建该响应的服务器时缓存服务器,Age值是指缓存后的响应再次发起认证到认证完成的时间值。代理创建响应时必须加上首部字段。 - Etag:
能告知客户端实体标识。它是一种可将资源以字符串形式做唯一性标识的方式,服务器会为每份资源分配对应的Etag值。 当资源更新时,也需要更新。
资源被缓存时,就会被分配唯一性标识。
强ETag:不论实体发生多么细微的变化都会改变其值。
弱ETag:只用于提示资源是否相同。只有资源发生了根本改变,产生差异时才会改变ETag值。这时,会在字段值最开始处附加W/。 - Location:
使用Location可以将响应接收方引导至某个与请求URI位置不同的资源。
基本上该字段会配合3XX:redirection的响应,提供重定向的URI。
一般都会强制性地尝试对已提示的重定向资源的访问。 - Proxy-Authenticate:
会把代理服务器所要求的认证信息发送给客户端。而客户端与服务器的认证会使用首部字段WWW-Authenticate。 - Retry-After
告知客户端应该在多久之后再次发送请求,主要配合503 Service Unavailable或3xx一起使用。
字段值可以指定为具体的日期时间,也可以是创建响应后的秒数 - Server
告知客户端当前服务器上安装的HTTP服务器应用程序的信息。 - Vary:
可对缓存进行控制。源服务器会向代理服务器传达关于本地缓存使用方法的命令。
若再要进行缓存,仅对请求中含有相同Vary指定首部字段的请求返回缓存。即使对相同资源发起请求,如果Vary指定的首部字段不相同,也必须从源服务器重新获取资源。 - WWW-Authenticate
用于HTTP访问认证。401 Unauthorized响应中,肯定带有该字段。
6.实体首部字段
实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。
- Allow:
用于通知客户端能够支持的所有HTTP方法。当服务器接收到不支持的HTTP方法时,会返回405 Method Not Allowed。与此同时,还会把所有能支持的HTTP方法写入首部字段Allow后返回。 - Content-Encoding
会告知客户端服务器对实体的主体选用的内容编码方式。内容编码是指不丢失信息的前提下进行的压缩 - Content-Language:
告知客户端,实体主体使用的自然语言 - Content-Length:
表明实体主体部分的大小。 - Content-Location:
给出与报文主体部分相对应的URI。和首部字段Location不同,该字段表示的是报文主体返回资源对应的URI。
比如,当返回的页面内容与实际请求的对象不同时,该字段会写明URI。 - Content-MD5:
是一串由MD5算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。
对报文主体执行MD5算法获得的128位二进制数,再通过Base64编码后将结果写入Content-MD5字段值。由于HTTP首部无法记录二进制值,所以要通过Base64编码处理。
作为接收方的客户端会对报文主体再执行一次相同的MD5算法。计算出的值与字段值相比较后,即可判断出报文主体的准确性。
PS:缺点:对内容上的偶发性改变是无从查证的,也无法检测出恶意篡改。原因在于:内容如果能够被篡改,那么意味着Content-MD5也可重新计算然后被篡改。 - Content-Range:
针对范围请求,返回响应时使用的首部字段,能告知客户端作为响应返回的实体的哪个部分符合范围请求。 如:Content-Range:bytes 5001-10000/10000 - Content-Type:
说明了实体主体内对象的媒体类型,和首部字段Accept一样,字段值用type/subtype形式赋值 - Expires:
会将资源失效的日期告知客户端。缓存服务器在接收到含有首部字段Expires的响应后,会以缓存来应答请求,在指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,会转向源服务器请求资源。
源服务器不希望缓存时,最好在Expires字段内写入与首部字段Date相同的时间值。
PS:在Cache-Control有指定max-age时,会优先处理max-age。 - Last-Modified:
指明资源最终修改的时间。
7.为Cookie服务的首部字段
- Cookie的工作机制是用户识别及状态管理。Web网站为了管理用户的状态会通过Web浏览器,把一些数据临时写入用户的计算机内。接着当用户访问该Web网站时,可通过通信方式取回之前发放的Cookie。
- 调用Cookie时,由于可校验Cookie的有效期,以及发送方的域、路径、协议等信息,所以正规发布的Cookie内的数据不会因来自其他Web站点和攻击而泄露。
- Set-Cookie:
当服务器准备开始管理客户端的状态时,会事先告知各种信息。
1.expires:指定浏览器可发送Cookie的有效期。当省略expires属性时,其有效期仅限于维持Session时间段内。 另外,一旦Cookie从服务器端发送至客户端,服务器端就不存在可以显式删除Cookie的方法。但可通过覆盖已过期的Cookie,实现对客户端Cookie的实质性删除操作。
2.path:Cookie的path属性可用于限制指定Cookie的发送范围的文件目录。(不安全)
3.domain:通过该属性指定的域名可做到与结尾匹配一致。比如指定example.com后,除了example.com以外,www.example.com和www2.example.com等都可以发送Cookie。
因此,除了针对具体指定的多个域名发送Cookie之外,不指定domain属性更安全。
4.secure:Cookie的该属性用于限制Web页面仅在HTTPS安全连接时,才可以发送Cookie。
5.HttpOnly:是Cookie的扩展功能,它使JavaSrcipt脚本无法获得Cookie,其主要目的是防止跨站脚本攻击(Cross-site Scripting,XSS)对Cookie的信息窃取。 - 首部字段Cookie会告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie。
8.其他首部字段
- HTTP首部字段是可以自行扩展的。所以会出现各种非标准的首部字段。