Http理解
参考资料:
刘望舒的blog
玉刚说
cache-control
木上有水的blog
一、Http的特性
1.灵活的
可以通过Content-Type和Content-Length传输任意类型的数据
2.无连接的
一次只完成一个请求,服务端处理完请求后会立即断开链接
3.无状态的
Http协议不会记录上一次连接的状态,如果想知道上一个连接的状态只能再次发起请求。
当然可以通过cookie和session来保存上一次连接的信息
二、URL的请求格式
http://host:port abs_path
host:指主机号
port:端口号,默认是80端口
abs_path:请求资源的url
三、报文格式
请求报文的格式通常是请求行,请求报头,请求体,请求数据
![](https://img.haomeiwen.com/i1593941/1df5cf83f4c20711.png)
响应报文不同的是会携带协议版本,响应状态码,响应的错误原因
![](https://img.haomeiwen.com/i1593941/7c80f607fa605568.png)
通用报头
既可以出现在请求报头,也可以出现在响应报头中
- Date:表示消息产生的日期和时间
- Connection:允许发送指定连接的选项,例如指定连接是连续的,或者指定“close”选项,通知服务器,在响应完成后,关闭连接
- Cache-Control:用于指定缓存指令,缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(一个消息的缓存指令不会影响另一个消息处理的缓存机制)
请求报头
请求报头通知服务器关于客户端求求的信息,典型的请求头有:
- Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机
- User-Agent:发送请求的浏览器类型、操作系统等信息
- Accept:客户端可识别的内容类型列表,用于指定客户端接收那些类型的信息
- Accept-Encoding:客户端可识别的数据编码
- Accept-Language:表示浏览器所支持的语言类型
- Connection:允许客户端和服务器指定与请求/响应连接有关的选项,例如这是为Keep-Alive则表示保持连接。
- Transfer-Encoding:告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式。
响应报头
用于服务器传递自身信息的响应,常见的响应报头:
- Location:用于重定向接受者到一个新的位置,常用在更换域名的时候
- Server:包含可服务器用来处理请求的系统信息,与User-Agent请求报头是相对应的
实体报头
实体报头用来定于被传送资源的信息,既可以用于请求也可用于响应。请求和响应消息都可以传送一个实体,常见的实体报头为:
- Content-Type:发送给接收者的实体正文的媒体类型
- Content-Lenght:实体正文的长度
- Content-Language:描述资源所用的自然语言,没有设置则该选项则认为实体内容将提供给所有的语言阅读
- Content-Encoding:实体报头被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码,因而要获得Content-Type报头域中所引用的媒体类型,必须采用相应的解码机制。
- Last-Modified:实体报头用于指示资源的最后修改日期和时间
- Expires:实体报头给出响应过期的日期和时间
四、Http缓存
我们请求服务器资源成功后,可以将请求的资源缓存在本地,当下次再使用时,可以使用本地的缓存,这样既节省了带宽又节省了时间。但是在使用本地缓存时首先有几个步骤
1. 新鲜度的检测
当我们想要使用本地缓存时,首先会向服务器验证资源是否过期。这个是通过Cache-Control(Http1.1)或者是Expire(Http1.0)来判断的。再第一次请求下数据时,服务器会对响应体追加Cache-Control:max-age,它表示这个缓存最多缓存多长时间。超过了这个时间需要向服务器验证请求的新鲜度。要结合last-modifed的时间:表示从上一次修改的时间+最大缓存时间表示它过期的时间
private 表示只对当前用户缓存
public 对所有用户缓存
no-cache:强制所有用户在使用缓存前需要向服务器再验证
only-if-cached:如果缓存存在,只使用缓存
2. 验证
如果已经超过了缓存时间,那么需要向服务器进行验证。如果验证通过可以使用本地缓存,服务端会响应304。,如果没有通过,服务器返回200,将最新的数据返回给客户端,验证的方式有:
If-Modified-Since
If-None-Match
If-Unmodified-Since
If-Range
If-Match
1.If-Modified-Since
将我们缓存的last-modifed时间取出来,并添加到If-Modified-Since中传递给服务器。告诉服务器我们缓存数据的这段时间,数据是否有更改。
2.If-None-Match和Etag
在首次请求一个url时,服务器会返回一个Etag标志,表示这个数据的版本,再下一次请求这个url时,我们会将这个Etag的值放到If-None-Match中,然后服务器会取出这个值和服务器缓存的值是否一致,如果一致代表缓存没有过期。
![](https://img.haomeiwen.com/i1593941/c894bf1ae65503cc.png)
四、实例:
模拟刷新了一个网页,可以看到浏览器类型是:Chrom 系统是Window。
请求类型是get,上一次修改的时间和服务器返回的修改时间一致,所以返回的是304,使用本地缓存。
![](https://img.haomeiwen.com/i1593941/a969628324b135a5.png)