前端http缓存
浏览器的http缓存机制分为强制缓存和协商缓存。
强制缓存
指的是浏览器第一次请求资源时,浏览器缓存在本地,并设定时间,如果在这个时间内再次请求,便会读取缓存的资源。对应策略为Expires 和 Cache-control,Cache-control的优先级高于Expires。强制缓存不会请求服务器。
Expires
我们用Pragma来禁用缓存,自然也需要有个东西来启用缓存和定义缓存时间,Expires就是做这件事的首部字段。
Expires的值对应一个GMT(格林尼治时间),比如“Mon, 22 Jul 2002 11:12:01 GMT”来告诉浏览器资源缓存过期时间,如果还没过该时间点则不发请求。
Cache-Control
Cache-Control也是一个通用首部字段,这意味着它能分别在请求报文和响应报文中使用。
请求报文中可选字段:
响应报文中可选字段:
若报文中同时出现了 Pragma、Expires 和 Cache-Control,会以 Cache-Control 为准
协商缓存
指的是文件最后修改时间是否相同或服务器判断文件是否被修改,来决定是否取缓存资源。对应策略为etag 和 last-modified.
Last-Modified
Last-Modified 是检验文件的最后修改时间是否与服务器上的文件相同,若一致,返回304状态吗, 否则返回412
Last-Modified 会有一些问题, 当文件的内容未修改,但是实际内容没变,会导致重新读取返回整个文件。
etag
为了解决Last-Modified不准的问题,http1.1 版本还推出了Etag首部字段。
服务器会通过某种算法,给资源计算得出一个唯一标志符(比如md5标志),在把资源响应给客户端的时候,会在实体首部加上“ETag: 唯一标识符”一起返回给客户端。
客户端会保留该 ETag 字段,并在下一次请求时将其一并带过去给服务器。服务器只需要比较客户端传来的ETag跟自己服务器上该资源的ETag是否一致,就能很好地判断资源相对客户端而言是否被修改过了。
如果服务器发现ETag匹配不上,那么直接以常规GET 200回包形式将新的资源(当然也包括了新的ETag)发给客户端;如果ETag是一致的,则直接返回304知会客户端直接使用本地缓存即可。
- If-None-Match: ETag-value
告诉服务器如果未匹配上资源,则需重发的资源,并返回304状态码 - If-Match: ETag-value
告诉服务器如果没有匹配到ETag,或者收到了“*”值而当前并没有该资源实体,则应当返回412(Precondition Failed) 状态码给客户端。否则服务器直接忽略该字段。
etag 的优先级比last-modified的高
禁用缓存
可以使用http1.0的标准 请求头上添加 program:no-cache,或者设置expires:no-cache; 或者 cache-control的max-age 设置一个过期时间。
Pragma
当该字段值为“no-cache”的时候(事实上现在RFC中也仅标明该可选值),会知会客户端不要对该资源读缓存,即每次都得向服务器发一次请求才行。