参考资料 :小林Coding、阿秀、代码随想录
一、HTTP缓存技术
将资源(如网页、图像、脚本等)的副本存储在客户端或中间代理服务器上,以便将来的请求可以直接从缓存中获取,而不必重新从服务器下载资源。这有助于减少网络延迟,提高页面加载速度,并减轻服务器的负担。
HTTP 缓存有两种实现方式,分别是强制缓存和协商缓存。
1. 强制缓存
浏览器判断请求的⽬标资源是否有效命中强缓存,如果命中,则可以直接从内存中读取⽬标资源,⽆需与服务器做任何通讯。
强缓存是利用下面两个 HTTP 响应头部(Response Header)字段实现的,它们都表示资源在客户端缓存的有效期:
- Cache-Control : http1.1 中增加该字段,使⽤ max-age 指令,可以设置资源在缓存中的最⻓有效时间,单位为秒。
- Expires :设置⼀个强缓存时间,此时间范围内,从内存中读取缓存并返回。
Cache-Control 的优先级高于 Expires
2. 协商缓存
与强制缓存不同,协商缓存依赖于客户端和服务器之间的交互,在协商缓存中,服务器在响应中提供了资源的⼀些标识信息,客户端在后续请求中通过这些信息来判断资源是否发⽣了变化,进⽽判断是否需要重新传输资源。
常用于协商缓存的⼀些头部字段:
1)ETag 和 If-None-Match
- ETag 是服务器为资源⽣成的唯⼀标识符,可以是根据⽂件内容计算出的哈希值。
- 客户端在请求头部的 If-None-Match 字段中携带上次响应的 ETag 值。
- 服务器比较请求中的 If-None-Match 值与当前资源的 ETag 值,如果匹配,表示资源未发⽣变化,返回状态码 304 Not Modified 。
2)Last-Modified 和 If-Modified-Since
- Last-Modified 是资源的最后修改时间,服务器在响应头部中返回
- 客户端在请求头部的 If-Modified-Since 字段中携带上次响应的 Last-Modified 时间。
- 服务器比较请求中的 If-Modified-Since 值与当前资源的 Last-Modified 值,如果请求时间早于资源的最后修改时间,表示资源未发生变化,返回状态码 304 Not Modified。
3. 缓存过期机制
max-age 指令出现在请求报⽂,并且缓存资源的缓存时间⼩于该指令指定的时间,表示该缓存未过期。
- max-age 指令出现在响应报⽂,表示缓存资源在缓存服务器中保存的时间。
- Expires ⾸部字段也可以⽤于告知缓存服务器该资源什么时候会过期。
在 HTTP/1.1 中,会优先处理 max-age 指令; 在 HTTP/1.0 中,max-age 指令会被忽略掉。
4. 禁用缓存
HTTP/1.1 通过 Cache-Control ⾸部字段来控制缓存。
- 禁止进行缓存 :no-store 指令规定不能对请求或响应的任何⼀部分进⾏缓存。
- 强制确认缓存 :no-cache 指令规定缓存服务器需要先向源服务器验证缓存资源的有效性,只有当缓存资源有效时才能使⽤该缓存 对客户端的请求进⾏响应
二、HTTP 版本更新
1. HTTP 1.0 和 HTTP 1.1 区别
HTTP 1.1 | HTTP 1.0 | |
---|---|---|
连接 | 支持长连接,每个TCP连接上可传送多个HTTP请求和响应,默认开启connection:Keep-Alive | 默认为短连接,每次请求都需要建立一个TCP连接 |
缓存 | 则引⼊了更多的缓存控制策略例如 Entity tag / If-None-Match 等更多可供选择的缓存头来控制缓存策略 | 主要使⽤ If-Modified-Since/Expires 来做为缓存判断的标准 |
管道化 | 管道化使得请求能够“并⾏”传输,但是响应必须按照请求发出的顺序依次返回,性能在⼀定程度上得到了改善。 | \ |
字段 | 增加Host字段,使得一个服务器能够用来创建多个Web站点。 | \ |
状态码 | 增加24个错误状态响应码 | \ |
带宽 | 在请求头引⼊了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content) | 存在⼀些浪费带宽的现象,例如客户端只是需要某个对象的⼀部分,⽽服务器却将整个对象送 过来了,并且不⽀持断点续传功能 |
2. HTTP 2.0 和 HTTP 1.1 区别
HTTP 2.0 | HTTP 1.1 | |
---|---|---|
传输格式 | 采用二进制,只认0/1组合,实现更加快,健壮性更加完整 | 解析是基于文本,文本表现形式多样,不利于健壮性考虑 |
多路复用 | 连接共享,一个请求对应一个ID,每个连接都可以有多个请求,接收方可以根据请求的ID将请求再次归属到不同的服务端请求中,极大提升效率。 | \ |
Header压缩 | 通过encoder减少Header大小,通讯双方会各自缓存一份Header字段表,既避免重复Header传输,又减小了需要传输的大小。 | Header带有大量信息,而且每次都要重复发送 |
服务端推送 | 把客户端所需要的资源伴随着index.html一起发送到客户端,省去了客户端重复请求的步骤。因为没有发起请求,建⽴连接等操作,所以静态资源通过服务器推送,可以极⼤的提升速度。 | \ |
三、一次完整的HTTP请求/响应过程
1. 客户端连接到Web服务器
- HTTP客户端(通常是浏览器),与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。
2. 发送HTTP请求
- 通过TCP套接字,客户端向Web服务器发送一个文本的请求报文。
3. 服务器接受请求并返回HTTP响应
- Web服务器解析请求,定位请求资源。服务器将资源副本写到TCP套接字,由客户端读取。
4. 释放TCP连接
- 若connection模式为close,服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;
- 若connection模式为keepalive。则该连接会保持一段时间,在该时间内可以继续接收请求;
5. 客户端浏览器解析HTML内容
- 客户端浏览器首先解析状态行,表明请求是否成功的状态代码;
- 然后解析每一个响应头,响应头告知以下若干字节的HTML文档和文档字符集。
- 客户端浏览器读取响应数据HTML,根据HTML语法对其进行格式化,并在浏览器窗口中显示。
四、在浏览器地址栏键入URL,按下回车之后会经历以下流程:
1. 浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
2. 解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立 TCP 连接;
3. 浏览器发出读取文件( URL 中域名后面部分对应的文件)的 HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器;
4. 服务器对浏览器请求作出响应,并把对应的 HTML 文本发送给浏览器;
5. 释放 TCP 连接;
6. 浏览器将该 HTML 文本并显示内容。