继续学习,冲鸭!
第6章 HTTP首部
6.1 HTTP报文首部
HTTP报文由报文首部和报文主体构成。
报文结构
HTTP请求报文
在请求中,HTTP报文由请求方法、HTTP协议版本,URL,请求首部字段等部分构成。
请求报文
HTTP响应报文
在响应中,HTTP报文由HTTP协议版本,状态码,HTTP首部字段等构成。
6.2 HTTP首部字段
6.2.1 HTTP首部字段传递重要信息
不必多说
6.2.2 HTTP首部字段结构
结构是字段名+字段值,一个字段可以有多个值。
首部字段如果重复会如何
视浏览器而定,有的按第一个,有的按最后一个。
6.2.3 4种HTTP首部字段类型
- 通用首部字段:请求和响应双方都会使用的字段;
- 请求首部字段:请求报文使用的首部字段;
- 响应首部字段:响应报文使用的首部字段;
- 实体首部字段:针对请求报文和响应报文实体部分使用的首部。补充了资源内容和更新时间等与实体有关的信息。
6.2.4 HTTP/1.1首部字段一览
通用首部字段请求首部字段
响应首部字段
实体首部字段
6.2.5 非HTTP/1.1首部字段
有Cookie、Set-Cookie、Content-Disposition等。
6.2.6 End-to-end首部和Hop-by-hop首部
端到端首部
分在此类别中的首部会转发给请求/响应对应的最终接受目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发。
个人理解:就是这个首部会一直被转发到终点。
逐跳首部
分在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再转发。HTTP/1.1和之后的版本中,如果要使用hop-by-hop首部,需提供Connection字段。
个人理解:一次性的转发,之后失效。
HTTP/1.1中的逐跳首部,除此之外都属于端到端首部。
6.3 HTTP/1.1通用首部字段
请求报文和响应报文都会使用的首部。
6.3.1 Cache-Control
控制缓存的工作机制。
Cache-Control指令一览
表示是否能缓存的指令
Ⅰpublic指令
Cache-Control:public
public明确表示其他用户也可以利用缓存。
Ⅱ private指令
Cache-Control:private
与public相反,响应只以特定用户作为对象。
Ⅲ no-cache指令
Cache-Control:no-cache
目的是为了防止从缓存中返回过期的资源。
一段有用的注释:
控制可执行缓存的对象的指令
no-store指令
Cache-Control:no-store
此指令暗示请求或响应中包含机密信息,不可在本地进行任何缓存。
指定缓存期限和认证的指令
Ⅰ s-maxage指令
Cache-Control:s-maxage=604800(单位:秒)
s-maxage指令和max-age指令功能基本相同,不同点在于前者只适用于供多位用户使用的公共缓存服务器,也就是说,对同一用户重复返回响应的服务器来说,这个指令是没有意义的。
Ⅱ max-age指令
若缓存在有效期内,客户端就接受资源。若max-age=0,缓存服务器会把请求转发给源服务器。
当服务器返回的响应包含max-age时,缓存服务器在指定的时间内不再对缓存的有效性进行确认。
max-age和Expires并存时,Expires会被忽略,在HTTP/1.0版本中,与此相反。
Ⅲ min-fresh指令
感觉与max-age一样,暂时没弄懂区别,有大神知道告诉我下。
Ⅳ max-stale指令
Cache-Control: max-stale=3600(单位:秒)
表示即使缓存过期,但只要过期时长没有超过指定时间,客户端依然会接受缓存。若没有指定时长,则不管过期多长时间,客户端都会接收。
Ⅴonly-if-cached指令
表示请求服务器上的缓存,缓存服务器不必再确认缓存的有效性。若缓存服务器没有缓存,会报504 Gateway Timeout
Ⅵ must-revalidate指令
如果使用这条指令,代理服务器会向源服务器验证当前缓存是否有效。若代理服务器无法连通源服务器,会报504GatewayTimeout。
使用must-revalidate会使max-stale失效
Ⅶ proxy-revalidate指令
Ⅷ no-transform指令
表示无论在请求还是响应中,缓存都不能改变实体主体的媒体类型,这可以防止缓存或代理服务器压缩图片等类似操作。
Cache-Control扩展
6.3.2 Connection
两个作用:
- 控制不再转发给代理的首部字段
- 管理持久连接
控制不再转发给代理的首部字段
管理持久连接
设置为Keep-Alive即可。
客户端若发起了Keep-Alive,服务端也会在响应报文首部字段中加上Connection:Keep-Alive。
6.3.3 Date
表明创建报文的日期和时间。
6.3.4 Pragma
HTTP/1.1之前版本的遗留字段。
Pragma: no-cache
为了兼容性,可以同时加上Cache-Control: no-cache和Pragma:no-cache。
6.3.5 Trailer
6.3.6 Transfer-Encoding
指定报文主体编码方式。
6.3.7 Upgrade
用于检测是否可以用更高的协议通信,服务器可用101 Switch Protocol状态码返回。
注意:Upgrade对象如果仅限于客户端和邻接服务器之间,需加上Connection:Upgrade,以确保该字段不再被转发。
6.3.8 Via
追踪报文的传输路径,可以防止避免回环
。
每个代理都会在这个字段中加入自己的信息,然后再进行转发。
6.3.9 Warning
告知用户与缓存相关的问题的警告。
类型:
HTTP/1.1警告码
6.4 请求首部字段
客户端发往服务器的报文中所使用的字段。
6.4.1 Accept
Accept- type/subtype中的subtype应该是type的子类型;
- q表示权重,最高为1,默认为1,表示对应的媒体类型的返回倾向;
-
通过设置Accept,可以避免接收浏览器不想接收的类型,比如浏览器不支持PNG,那accept就不指定image/png,而制定image/jpeg等可处理的类型。
常用媒体类型:
6.4.2 Accept-Charset
用于告知服务器客户端支持的字符集以及字符集的优先顺序,可以一次指定多个字符集,可以通过通过设置权重q来安排有限顺序。
6.4.2 Accept-Encoding
用于告知服务器客户端支持的内容编码以及编码的有限顺序。
常用的内容编码:
个人理解:就是指定压缩格式。
6.4.4 Accept-Language
这个很容易理解了。
6.4.5 Authorization
用于向服务器发送用户代理的认证信息。
6.4.6 Expect
客户端使用Expect来告知服务器,期望服务器出现某种特定的行为。如果服务器服务无法理解客户端发出的期望,会返回状态码417 Expectation Failed.
比如客户端希望服务器返回状态码100 Continue, 发送Expect:100-continue。
6.4.7 From
指定电子邮件。
6.4.8 Host
用户告知服务器请求的资源所处的互联网主机和端口号。
由于一台服务器可能存在多个不同域名的虚拟主机,所以单单依靠ip无法正确区分要访问哪个主机,这就需要Host字段来指出请求的主机名。
6.4.9 If-Match
附带条件的请求:
形如If-xxxx的请求,称之为条件请求,服务器接收到这样的请求后,之有条件判断为真,才会执行请求。
If-Match: "123456"
If-Match 用于指定想要获取的资源的ETag值,只有在资源的ETag值与之相同时,服务器才会执行请求,否则会返回状态码412 Precondition Failed。
若使用*号指定If-Match,那么服务器就不会对ETag进行比对,直接返回资源。
6.4.10 If-Modified-Since
客户端指定所要的资源要在某个时间过后要发生更新,如果不符合要求,服务器会返回304 Not Modified错误。
6.4.11 If-None-Match
与If-Match相反
6.4.12 If-Range
使用If-Range和不使用If-Range的对比
不使用If-Range
If-Range指定所请求的资源的ETag值或者时间,当对应资源的ETag或者时间与之相同时,返回所指定范围的资源,否则的话返回全部资源。
如果不使用If-Range,仍然可以用Range发起范围请求,并用If-Match指定ETag值或时间,但是若对应的资源的ETag值或时间不相同时,会返回状态码412 Precondition Failed,催促客户端再次发起请求来请求全部资源,这样就会花费两倍的时间。
6.4.13 If-Unmodified-Since
与If-Modified-Since相反。
6.4.14 Max-Forwards
用来指定可经过的服务器的最大数目,类似于TTL。
可以用Max-Forwards对传输路径的通信状况有所把握,也可以防止陷入循环。
6.4.15 Proxy-Authorization
响应
代理服务器
发来的认证质询。6.4.16 Range
用于只需要获取部分资源的范围请求。服务器如果成功处理范围请求,会返回206 Partial Content响应,否则返回状态码200 OK和全部资源。
6.4.17 Rerferer
6.4.18 TE
6.4.19 User-Agent
不必多说。
6.5 响应首部字段
服务器向客户端发送的响应报文中所使用的字段。
6.5.1 Accept-Ranges
服务器用来告诉客户端自身能否处理范围请求。
6.5.2 Age
这个感觉说的不清楚,从网上查资料得知:
Age字段的定义:当代理服务器用自己缓存的实体去响应请求时,用该头部表明该实体从产生到现在经过多长时间了
.
6.5.3 ETag
首部字段ETag以字符串的方式告知客户端资源的实体标识。服务器会对每一份资源作相应的唯一ETag标识。
当资源更新时,ETag值也要相应更新,生成值没有统一算法,仅由服务器来支配。
ETag有强弱之分
- 强ETag:无论实体发生了多么微小的变化都会改变其值。
- 弱ETag:只用于提示资源是否相同,只有发生了根本改变才会改变ETag值。字段开始处会附加W/。
强ETag
弱ETag
6.5.4 Location
将客户端重新引导至某个资源。
6.5.5 Proxy-Authenticate
把
代理服务器
所要求的认证信息发送给客户端。6.5.6 Retry-After
告知客户端发起下次请求的间隔时间
6.5.7 Server
告知客户端安装在服务器上的HTTP服务器应用程序的信息。
6.5.8 Vary
源服务器用Vary向代理服务器传达缓存使用方法的命令。
比如:
Vary: Accept-Language
当客户端请求中的Accept-Language字段与缓存相同时才可返回缓存,否则缓存服务器就要向源服务器重新获取资源。
6.5.9 WWW-Authenticate
6.6 实体首部字段
实体首部字段是包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。
6.6.1 Allow
- 用来告知服务器URL所指定资源的支持的所有HTTP方法;
- 当服务器接收到不支持的HTTP方法时,会返回405 Method Not Allowed方法,与此同时,还会把所有支持的HTTP方法写在Allow中返回。
6.6.2 Content-Encoding
服务器用来告知客户端对实体信息选用的编码方式,内容编码是指在不丢失实体信息的前提下进行的。
6.6.3 Content-Language
这个很明显了。
6.6.4 Content-Length
表明实体主体的大小,单位为字节。当主题采用了内容编码传输时,不可以使用此首部字段。
6.6.5 Content-Location
指出返回资源所对应的URL。
比如,当返回的对象与所请求的不同时,首部字段Content-Location会写明URL。
6.6.6 Content-MD5
字段中的值是由MD5算法根据报文主体内容生成的值,目的在于内容是否在传输中保持完整。算法的结果是二进制数,而HTTP首部无法记录二进制数,所有需以Base64编码进行再次处理。
这种方法并不能确保安全,因为篡改了内容后照样可以再次生成对应的字段值。
6.6.7 Content-Range
6.6.8 Content-Type
指出实体主体内对象的媒体类型,还可以说明采用的字符集。
6.6.9 Expires
用来告知资源失效的日期。
当缓存服务器接收到含有Expires的响应后,在Expires时间内,缓存会一直被保留,当超过指定的时间后收到对资源的请求时会向源服务器再次请求资源。
如果源服务器不希望缓存服务器对资源进行缓存,最好把Expires字段内的值设为与Date相同。
max-age存在时,会忽略Expires。
6.6.10 Last-Modified
指明资源最后的修改时间。
6.7 为Cookie服务的首部字段
分为Set-Cookie和Cookie。
6.7.1 Set-Cookie
- expires字段指明Cookie的有效期,省略expires时,有效期一般仅限于浏览器程序被关闭之前。可以通过覆盖Cookie来实现Cookie的删除操作,不存在显式的删除操作;
- 使用HttpOnly时,JavaScript的document.cookie就无法读取Cookie的内容了。
6.7.2 Cookie
6.8 其它首部字段
Http首部字段是可以自行扩展的,因此会出现一些非标准首部字段。
6.8.1 X-Frame-Options
6.8.2 X-XSS-Protection
6.8.3 DNT
设置进制追踪。
6.8.4 P3P
最后:
更详细内容可以参考HTTP开发者手册
网友评论