HTTP缓存介绍

Http协定里包含了掌握缓存的部份,以使Http客户端可以缓存和重用之前获得的资源,从而优化性状,晋升体验。

在开发Web服务时,只须要关注要求头If-None-Match、响应头ETag、响应头Cache-Control就足够了。由于这三个Http头便可以满足你的需求,并且,当今绝大多数的浏览器,都支撑这三个Http头。

响应头ETag

ETag全称Entity Tag,用来标识一个资源。在具体的实现中,ETag可以是资源的hash值,也能够是一个内部保护的版本号。但不管怎样,ETag应该能反应出资源内容的变更,这是Http缓存可以正常工作的基本。

服务器在返回响应时,通常会在Http头中包含一些关于响应的元数据信息,其中,ETag就是其中一个,本例中返回了值为x1323ddx的ETag。当资源/file的内容产生变更时,服务器应该返回不同的ETag。

要求头If-None-Match

对同一个资源,比如上一例中的/file,在进行了一次要求以后,浏览器就已有了/file的一个版本的内容,和这个版本的ETag,当下次用户再须要这个资源,浏览器再次向服务器要求的时候,可以应用要求头If-None-Match来告知服务器自己已有个ETag为x1323ddx的/file,这样,如果服务器上的/file没有变更,也就是说服务器上的/file的ETag也是x1323ddx的话,服务器就不会再返回/file的内容,而是返回一个304的响应,告知浏览器该资源没有变更,缓存有效。

响应头Cache-Control

每一个资源都可以通过Http头Cache-Control来定义自己的缓存策略,Cache-Control掌握谁在甚么条件下可以缓存响应和可以缓存多久。最快的要求是不必与服务器进行通讯的要求:通过响应的本地副本,我们可以免所有的网络延迟和数据传输的数据本钱。为此,HTTP 规范许可服务器返回一系列不同的 Cache-Control 指令,掌握浏览器或其他中继缓存如何缓存某个响应和缓存多长时光。

Cache-Control 头在 HTTP/1.1 规范中定义,取代了之前用来定义响应缓存策略的头(例如 Expires)。当前的所有浏览器都支撑 Cache-Control,因此,应用它就够了。

以下我来介绍可以再Cache-Control中设置的常常使用指令。

max-age

该指令指定从当前要求开端,许可获得的响应被重用的最长时光,单位为秒。Cache-Control:max-age=60 表现响应可以再缓存和重用 60 秒。须要注意的是,在max-age指定的时光之内,浏览器不会向服务器发送任何要求,包括验证缓存是不是有效的要求,也就是说,如果在这段时光之内,服务器上的资源产生了变更,那末浏览器将不能得到通知,而应用老版本的资源。所以在设置缓存时光的长度时,须要郑重。

public和private

如果设置了public,表现该响应可以再浏览器或任何中继的Web代理中缓存,public是默许值,即Cache-Control:max-age=60同等于Cache-Control:public, max-age=60

在服务器设置了private比如Cache-Control:private, max-age=60的情形下,表现只有用户的浏览器可以缓存private响应,不准可任何中继Web代理对其进行缓存。例如,用户浏览器可以缓存包含用户私人信息的 HTML 网页,但是 CDN 不能缓存。

no-cache

如果服务器在响应中设置了no-cache即Cache-Control:no-cache,那末浏览器在应用缓存的资源之前,必需先与服务器确认返回的响应是不是被更改,如果资源未被更改,可以免下载。这个验证之前的响应是不是被修改,就是通过上面介绍的要求头If-None-match和响应头ETag来实现的。

须要注意的是,no-cache这个名字有一点误导。设置了no-cache以后,其实不是说浏览器就不再缓存数据,只是浏览器在应用缓存数据时,须要先确认一下数据是不是还跟服务器保持一致。如果设置了no-cache,而ETag的实现没有反应出资源的变更,那就会致使浏览器的缓存数据一直得不到更新的情形。

no-store

如果服务器在响应中设置了no-store即Cache-Control:no-store,那末浏览器和任何中继的Web代理,都不会存储这次相应的数据。当下次要求该资源时,浏览器只能重新要求服务器,重新从服务器读取资源。

缓存策略

怎样决议一个资源的Cache-Control策略呢?下面这个流程图,可以帮到你: