http缓存
本文最后更新于:2023年8月15日 下午
缓存
缓存的主要作用是减少没有必要的请求,减少服务器压力的同时也能提升前端页面的性能;
简易流程:
第一次请求的时候浏览器把资源下载下来,这个http的response里面就会包含一些字段(expires,cache-control,pragma等)标识这个资源能不能被缓存,如果能被缓存到浏览器本地,他就是个强缓存,
在强缓存过期之后(或者直接刷新页面,或者no-cache等情况),浏览器就会请求服务端获取该资源,服务端判断资源是否过期,未过期就304告诉浏览器去取本地缓存,这个就是协商缓存,
如果过期了那就相当于重新请求了,http状态码200。
下面主要介绍强缓存和协商缓存:
强缓存
- 概念
直接使用本地的缓存,不用跟服务器进行通信,http状态码是200,显示from memery 或者 from disk,这个存在哪里是浏览器控制的。
- 相关header字段
2.1 expires
这是http1.0中定义的字段,它是一个服务器时间的格林威治时间戳,但是是拿客户端本地的时间和这个时间戳对比判断的,客户端的本地时间可以修改,不靠谱,所以不好用。
2.2 cache-control
http1.1中的字段,为了解决上面expires的问题而新增的,优先级高于 expires。
它是一个相对时间段,请求有效的最大时间段,比如max-age:30,代表请求时间点加30秒之后就无效了,
因为它是一个时间段,所以意味着,可以设置一些默认值,
常见的默认值设置:
pubilc: 客户端和代理服务器cdn等都可以缓存该资源;
private: 只让客户端可以缓存该资源;代理服务器不缓存;
immutable:如果缓存在有效期内,即使用户刷新了页面也不请求服务器(正常情况下刷新页面是忽略是否有效,请求服务器走协商缓存的);
no-cache:不强缓存,相当于直接走协商缓存(刷新页面的操作就是no-cache);
no-store:没有强缓存和协商缓存了,禁止浏览器和服务器缓存数据,也禁止保存至临时文件中,每次都重新请求。
2.3 pragma
这是也是http1.0的字段,正在逐步抛弃,但是他也是有效的,而且优先级 pragma > cache-control > expires,他有两个值no-cache和no-store,效果是和cache-control一样的。
协商缓存
- 概念
本地缓存过期或者其他原因(no-cache,刷新等等),浏览器会请求服务端判断文件是否依然有效,这就是协商缓存。
- 相关header字段
2.1 last-modified
response会返回这个字段,代表文件最后一次编辑的时间,浏览器再次请求该文件时request会有一个if-modified-since字段,他俩就是一个意思,如果相同说明没修改,http304告诉浏览器还用本地的,如果不同那就返回新文件同时更新文件的last-modified(也更新etag)。
但是这玩意有两个不好的地方:
1、无论内容是否真的变化,只要编辑就会修改last-modified;
2、last-modified只能精确到秒,如果在一秒内文件修改了,last-modified就判断未修改,取缓存会造成错误。
2.2 etag
etag也是为了解决上面的last-modified问题出现的,etag是基于文件内容生成的一个字符串,我个人简单理解为类似于文件md5,etag对文件变化感知更精确,所以优先级高于last-modified,etag是response里面的字段,在request里面叫if-none-matched
刷新操作对缓存的影响:
1、刷新页面实际上是把cache-control设置成了max-age:0,相当于不判断本地是否过期,直接走协商缓存;
2、强制刷新是跳过缓存,相当于第一次请求资源。
no-cache 和 max-age:0 在一般情况下的表现效果是一致的,区别在于前者是must,后者是should,如果服务器端发生错误,没有返回新的文件,
那么max-age的文件是勉强可以用的,no-cache的文件是绝对不能使用的
参考链接:(这几篇文章真的好)
https://www.jianshu.com/p/9c95db596df5