缓存
关于HTTP字段参考HTTP首部字段
一、优点
- 缓解服务器压力
- 降低客户端获取资源的延迟(缓存资源比服务器上的资源离客户端更近)
二、实现方法
- 让客户端浏览器进行缓存
- 让代理服务器进行缓存
三、Cache-Control
HTTP/1.1通过Cache-Control首部字段来控制缓存
3.1、禁止进行缓存
Cache-Control: no-store
no-store
规定不能对请求或者响应的任何一部分进行缓存
3.2、强制确认缓存
Cache-Control: no-cache
no-cache
指令规定缓存服务器需要先向源服务器验证缓存资源的有效性,只有当缓存资源有效才将能使用该缓存对客户端的请求进行响应。
3.3、私有缓存和公有缓存
Cache-Control: private
private
指定规定了可以将资源作为私有缓存,只能被单独用户所使用,一般存储在用户浏览器中。
Cache-Control: public
public
指令规定了可以将资源作为公共缓存,可以被多个用户所使用,一般存在在代理服务器中。
四、缓存过期机制
max-age = delta-seconds
指令出现在请求报文中,则表示告知服务器客户端希望接收一个存在时间(Age)不大于
delta-seconds
秒的缓存资源。指令出现在响应报文中,则表示告知客户端该资源在
delta-seconds
秒内是新鲜的,无需向服务器进行请求验证。
Expires: Wed, 04 Jul 2012 08:26:05 GMT
实体首部字段Expires
字段也可以用于告知浏览器或者缓存服务器该资源什么时候会过期,如果没过该时间则不发送请求。在 HTTP/1.1 中,会优先处理 Cache-Control : max-age
指令;而在 HTTP/1.0 中,Cache-Control : max-age
指令会被忽略掉。
但是响应报文中Expires所定义的缓存时间是相对服务器上的时间而言的,如果客户端上的时间跟服务器上的时间不一致(特别是用户修改了自己电脑的系统时间),那缓存时间可能就没啥意义了。
五、缓存验证
需要先了解响应首部字段 ETag
的含义,它是资源的唯一表示。URL 不能唯一表示资源,例如 http://www.google.com/
有中文和英文两个资源,只有 ETag
才能对这两个资源进行唯一表示。
ETag: "82e22293907ce725faf67773957acd12"
可以将缓存资源的 ETag
值放入 If-None-Match
首部,服务器收到该请求后,判断缓存资源的 ETag
值和资源的最新 ETag
值是否一致,如果一致则表示缓存资源有效,返回 304 Not Modified
。
If-None-Match: "82e22293907ce725faf67773957acd12"
Last-Modified 首部字段也可以用于缓存验证,它包含在源服务器发送的响应报文中,指示源服务器对资源的最后修改时间。但是它是一种弱校验器,因为只能精确到一秒,所以它通常作为 ETag
的备用方案。
如果响应首部字段里含有这个信息,客户端可以在后续的请求中带上 If-Modified-Since
来验证缓存。服务器只在所请求的资源在给定的日期时间之后对内容进行过修改的情况下才会将资源返回,状态码为 200 OK
。如果请求的资源从那时起未经修改,那么返回一个不带有消息主体的 304 Not Modified
响应。
//客户端
Last-Modified: Wed, 21 Oct 2015 07:28:00 GM
//服务器
If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT
六、连接管理
6.1、短连接与长连接
当浏览器访问一个包含多张图片的 HTML 页面时,除了请求访问 HTML 页面资源,还会请求图片资源,如果每进行一次 HTTP 通信就要断开一次 TCP 连接,连接建立和断开的开销会很大,这就是短连接。长连接只需要建立一次 TCP 连接就能进行多次 HTTP 通信。
HTTP/1.1
开始默认是长连接的,如果要断开连接,需要由客户端或者服务器端提出断开,使用 Connection : close
;而在 HTTP/1.1
之前默认是短连接的,如果需要长连接,则使用 Connection : Keep-Alive
。
6.2、流水线
默认情况下,HTTP 请求是按顺序发出的,下一个请求只有在当前请求收到应答过后才会被发出。由于会受到网络延迟和带宽的限制,在下一个请求被发送到服务器之前,可能需要等待很长时间。流水线是在同一条长连接上发出连续的请求,而不用等待响应返回,这样可以避免连接延迟。