如何禁止浏览器缓存html页面
<meta http-equiv="Cache-Control" content="no-cache,no-store,must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
HTTP 协议中使用头信息控制缓存信息, 包括浏览器端,中间缓存服务器端,Web服务器端。HTTP协议中用于缓存信息头关键字包括:
Pragma HTTP 1.0 版本使用 Cache-Control HTTP 1.1 版本使用 Expires 过期时间 last-Modified 最近修改的时间
我们从两个角度来看看http的缓存:缓存控制和缓存校验。
- 缓存控制:控制缓存的开关,用于标识请求或访问中是否开启了缓存,使用了哪种缓存方式。
- 缓存校验:如何校验缓存,比如怎么定义缓存的有效期,怎么确保缓存是最新的。
缓存控制
在http中,控制缓存开关的字段有两个:Pragma 和 Cache-Control。
Pragma
Pragma有两个字段Pragma和Expires。
Pragma的值为no-cache时,表示禁用缓存。Expires的值是一个GMT时间,表示该缓存的有效时间。
Pragma是旧产物,已经逐步抛弃,有些网站为了向下兼容还保留了这两个字段。
如果一个报文中同时出现Pragma和Cache-Control时,以Pragma为准。
同时出现Cache-Control和Expires时,以Cache-Control为准。
- 优先级从高到低是 Pragma -> Cache-Control -> Expires
Cache-Control
符合缓存策略时,服务器不会发送新的资源,但不是说客户端和服务器就没有会话了,客户端还是会发请求到服务器的。
Cache-Control 除了在响应中使用,在请求中也可以使用。
我们用开发者工具来模拟下请求时带上Cache-Control:勾选Disable cache,刷新页面,可以看到Request Headers中有个字段 Cache-Control: no-cache。 同时在Response Headers中也能到Cache-Control字段,它的值是must-revalidate,这是服务端设置的。
- 请求中使用Cache-Control可用值
| 字段 | 含义 | | -- | -- | | no-cache | 告知(代理)服务器不能直接使用缓存,要求向源服务器发起请求 | | no-store | 所有内容都不会被保存到缓存或 Internet 临时文件中 | | max-age-delta-seconds | 告知服务器,客户端希望接收一个存在时间(Age)《=delta-seconds秒的资源 | | max-stale [=delta-seconds] | 告知(代理)服务器,客户端愿意接受一个超过缓存时间的资源,若有定义delta-seconds 则为 delta-seconds,否则为任意时间。 | | min-fresh=delta-seconds | 告知(代理)服务器,客户端希望接受一个在小于delta-seconds秒内被更新过的资源 | | no-transform | 告知(代理)服务器,客户端希望获取实体数据没有被转换过的资源(如压缩) | |only-if-cached | 告知(代理)服务器,客户端希望获取缓存的内容(若有),而不用向原服务器发请求 | | cache-extension | 自定义扩展值,若服务器不识别该值将被忽略掉 |
缓存校验
在缓存中,我们需要一个机制来验证缓存是否有效。比如服务器的资源更新了,客户端需要及时刷新缓存;又或者客户端的资源过了有效期,但服务器上的资源还是旧的,此时并不需要重新发送。缓存校验就是用来解决这些问题的,在http 1.1 中,我们主要关注下Last-Modified 和 etag 这两个字段。
Last-Modified
服务端在返回资源时,会将该资源的最后更改时间通过Last-Modified字段返回给客户端。客户端下次请求时通过If-Modified-Since或者If-Unmodified-Since带上Last-Modified,服务端检查该时间是否与服务器的最后修改时间一致:如果一致,则返回304状态码,不返回资源;如果不一致则返回200和修改后的资源,并带上新的时间。
- If-Modified-Since:告诉服务器如果时间一致,返回状态码304
- If-Unmodified-Since:告诉服务器如果时间不一致,返回状态码412
etag
单纯的以修改时间来判断还是有缺陷,比如文件的最后修改时间变了,但内容没变。对于这样的情况,我们可以使用etag来处理。
etag的方式是这样:服务器通过某个算法对资源进行计算,取得一串值(类似于文件的md5值),之后将该值通过etag返回给客户端,客户端下次请求时通过If-None-Match或If-Match带上该值,服务器对该值进行对比校验:如果一致则不要返回资源。
- If-None-Match:告诉服务器如果一致,返回状态码304,不一致则返回资源
- If-Match:告诉服务器如果不一致,返回状态码412