强缓存
强缓存主要使用Expires、Cache-Control 两个头字段,两者同时存在Cache-Control 优先级更高。当命中强缓存的时候,客户端不会再请求,直接从缓存中读取内容,并返回HTTP状态码200。
- Cache-Control 请求/响应头,缓存控制字段,精确控制缓存策略。
- Expires 响应头,代表该资源的过期时间。是一个GMT 格式的标准时间。
Cache-Control 服务端参数:
- max-age: 在多少秒内有效,是一个相对时间,这样比Expires具体的时间就更精确了。
- s-maxage: 就是用于表示 cache 服务器上(比如 cache CDN,缓存代理服务器)的缓存的有效时间的,并只对 public 缓存有效。
- no-cache:不使用本地强缓存。需要使用缓存协商。
- no-store:直接禁止浏览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。
- public:可以被所有的用户缓存,包括终端用户和中间代理服务器。
- private:只能被终端用户的浏览器缓存,不允许中间缓存代理进行缓存,默认的。
Cache-Control 客户端参数:
- max-stale: 5 表示客户端到代理服务器上拿缓存的时候,即使代理缓存过期了也不要紧,只要过期时间在 5 秒之内,还是可以从代理中获取的。
- min-fresh: 5 表示代理缓存需要一定的新鲜度,不要等到缓存刚好到期再拿,一定要在到期前 5 秒之前的时间拿,否则拿不到。
- only-if-cached 这个字段加上后表示客户端只会接受代理缓存,而不会接受源服务器的响应。如果代理缓存无效,则直接返回 504(Gateway Timeout)。
协商缓存
协商缓存主要有四个头字段,它们两两组合配合使用。Etag 和 If-None-Match一组,If-Modified-Since 和 Last-Modified一组,当同时存在的时候会以Etag 和 If-None-Match为主。。当命中协商缓存的时候,服务器会返回HTTP状态码304,让客户端直接从本地缓存里面读取文件。
Etag 和 If-None-Match
- Etag:响应头,资源标识,由服务器告诉浏览器。
- If-None-Match:请求头,缓存资源标识,由浏览器告诉服务器。其实就是第一次访问服务端返回的Etag的值。
Etag 是由文件修改时间与文件大小计算而成,只有当文件文件内容或修改时间变了Etag的值才会发生变化。 当客户端第一次请求服务器的时候,服务端会返回一个Etag响应头。客户端请求服务器的时候会带上If-None-Match请求头字段,该字段的值就是服务器返回的Etag的值。服务器接收到请求后会比较这两个值是否一样,一样就返回304,让客户端从缓存中读取,不一样就会返回新文件给客户端并更新Etag响应头字段的值。 优点:
- 当缓存有效时服务器不会返回文件给客户端,而是直接返回304状态码,让客户端从缓存中获取文件。大大节省了流量和带宽以及服务器的压力。
- 并且解决了一秒内修改并读取的问题。
If-Modified-Since 和 Last-Modified
-
If-Modified-Since:请求头,资源最近修改时间,由浏览器告诉服务器。其实就是第一次访问服务端返回的Last-Modified的值。
-
Last-Modified:响应头,资源最近修改时间,由服务器告诉浏览器。
当客户端第一次请求服务器的时候,服务端会返回一个Last-Modified响应头,该字段是一个标准时间。客户端请求服务器的时候会带上If-Modified-Since请求头字段,该字段的值就是服务器返回的Last-Modified的值。服务器接收到请求后会比较这两个值是否一样,一样就返回304,让客户端从缓存中读取,不一样就会返回新文件给客户端并更新Last-Modified响应头字段的值。
优点:当缓存有效时服务器不会返回文件给客户端,而是直接返回304状态码,让客户端从缓存中获取文件。大大节省了流量和带宽以及服务器的压力。
缺点:不一定能获取到最新文件,Last-Modified 过期时间只能精确到秒。如果在同一秒既修改了文件又获取文件,客户端是获取不到最新文件的。
缓存位置
按缓存位置分类我们可以分为memory cache、disk cache、Service Worker三类
- memory cache 是内存中的缓存,(与之相对 disk cache 就是硬盘上的缓存)。按照操作系统的常理:先读内存,再读硬盘。
- disk cache 也叫 HTTP cache,顾名思义是存储在硬盘上的缓存,因此它是持久存储的,是实际存在于文件系统中的。而且它允许相同的资源在跨会话,甚至跨站点的情况下使用,例如两个站点都使用了同一张图片。
- service work给予了我们另外一种更加灵活,可以直接的操作方式。我们可以从 Chrome 的 Application找到Service Workers。这个缓存是永久性的,即关闭 TAB 或者浏览器,下次打开依然还在(而 memory cache 不是)。有两种情况会导致这个缓存中的资源被清除:手动调用 API
cache.delete(resource)或者容量超过限制,被浏览器全部清空。