前端缓存之http缓存
浏览器缓存
1、浏览器第一次打开一个网页获取资源后,根据返回的header(响应头)信息来告诉如何缓存资源。
2、浏览器后续请求
3、浏览器在请求某一资源时,会先获取该资源缓存的header信息,判断是否命中强缓存(cache-control和expires信息),若命中直接从缓存中获取资源信息,包括缓存header信息,本次请求不会与服务器进行通信,此时返回的状态码为200
4、如果没有命中强缓存,浏览器会发送请求到服务器,请求会携带第一次返回的有关缓存的header字段信息(Last-Modified/If-Modified-Since 和 etag/If-None-Match)
5、由服务器根据header信息来对比结果是否协商缓存命中。若命中,则服务返回新的响应头header信息更新缓存中的对应header信息,和304状态码,但是不会返回资源内容,它会告知浏览器可以直接从缓存获取;否则返回最新的资源内容。
// 协商缓存
// 第一次返回的响应头
Last-Modified: Mon, 02 Jul 2018 08:21:56 GMT
etag: "20e340c70bd7c739e5e633b5c0ee705a"
// 如果强缓存失效,则请求的时候,浏览器会带上第一次响应头的Last-Modified 和 etag的值得
If-Modified-Since: Mon, 02 Jul 2018 08:21:56 GMT // 上次返回的Last-Modified的值
If-None-Match: "20e340c70bd7c739e5e633b5c0ee705a" // 上次返回的etag的值
流程图如下:
强缓存与协商缓存的区别:
缓存 | 获取资源形式 | 状态码 | 发送请求到服务器 |
---|---|---|---|
强缓存 | 从缓存取 | 200(from cache) | 否,直接从缓存取 |
协商缓存 | 从缓存取 | 304(not modified) | 是,通过服务器告知浏览器缓存是否可用 |
协商缓存header字段
响应头信息:
1.etag:服务器响应时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。
2.Last-Modified:表示这个响应资源的的最后修改时间。
请求头信息:
1.If-None-Match: 当资源过期时候,浏览器法相响应头里有Etag,则再次向服务器请求时带上请求头if-none-match(值是etag的值)。服务器收到请求进行对比,决定返回200 或者304
2、If-Modified-Since:当资源过期时(浏览器判断cache-control标识的max-age过期),发现响应头具有last-Modified声明,则再次像服务器请求时带上if-modified-since,表示请求时间。服务器收到请求后发现有if-modified-since则与被请求资源的最后修改时间进行对比(last-modified),若修改时间较新(大),说明资源又被改过,则返回最新资源,http 200 ok。若最后时间较小,说明资源无修改,响应http 304走缓存
为什么既有last-modified 还有etag,两者并存的好处?
http1.1中etag的出现主要是为了解决几个last-modified比较难解决的问题
一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)。
某些服务器不能精确的得到文件的最后修改时间。
这时,利用Etag能够更加准确的控制缓存,因为Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符。
Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。
用户行为对缓存的影响
用户操作 | Expires/Cache-Control | Last-Modified/Etag |
---|---|---|
地址栏回车 | 有效 | 有效 |
页面链接跳转 | 有效 | 有效 |
新开窗口 | 有效 | 有效 |
前进后退 | 有效 | 有效 |
F5刷新 | 无效 | 有效 |
Ctrl+F5强制刷新 | 无效 | 无效 |
文章只是之前在网上学习的笔记,如有雷同,请联系