网络上解决缓存的方法
//针对html缓存,只要加上下面内容
//但加了下面内容经常还是无效
<meta http-equiv="Expires" content="0">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-control" content="no-cache">
<meta http-equiv="Cache" content="no-cache">
//针对css和js缓存,在引用后面加上随机数
<script src="../scripts/register.js?v=20161020"></script>
缓存介绍
缓存优点
通常所说的Web缓存指的是可以自动保存常见http请求副本的http设备。当Web请求到达缓存时,缓存从本地副本中提取这个副本内容而不需要经过服务器。这带来了以下优点:
- 缓存减少了冗余的数据传输,节省流量
- 缓存缓解了带宽瓶颈问题。不需要更多的带宽就能更快加载页面
- 缓存缓解了瞬间拥塞,降低了对原始服务器的要求。
- 缓存降低了距离延时, 因为从较远的地方加载页面会更慢一些。
缓存处理流程
注意,我们讨论的所有关于缓存资源的问题,都仅仅针对GET请求。而对于POST, DELETE, PUT这类行为性操作通常不做任何缓存。
新鲜度限值
HTTP通过缓存将服务器资源的副本保留一段时间,这段时间称为新鲜度限值。这在一段时间内请求相同资源不会再通过服务器。HTTP协议中Cache-Control 和 Expires可以用来设置新鲜度的限值,前者是HTTP1.1中新增的响应头,后者是HTTP1.0中的响应头。二者所做的事时都是相同的,但由于Cache-Control使用的是相对时间,而Expires可能存在客户端与服务器端时间不一样的问题,所以我们更倾向于选择Cache-Control。
Cache-Control
下面我们来看看Cache-Control都可以设置哪些属性值:
- max-age(单位为s)指定设置缓存最大的有效时间,定义的是时间长短。当浏览器向服务器发送请求后,在max-age这段时间里浏览器就不会再向服务器发送请求了。
- public 指定响应可以在代理缓存中被缓存,于是可以被多用户共享。如果没有明确指定private,则默认为public。
- private 响应只能在私有缓存中被缓存,不能放在代理缓存上。对一些用户信息敏感的资源,通常需要设置为private。
- no-cache 表示必须先与服务器确认资源是否被更改过(依靠If-None-Match和Etag),然后再决定是否使用本地缓存。
- no-store 绝对禁止缓存任何资源,也就是说每次用户请求资源时,都会向服务器发送一个请求,每次都会下载完整的资源。通常用于机密性资源。
关于Cache-Control的使用,见下面这张图
Cache-Control不仅仅可以在响应头中设置,还可以在请求头中设置。浏览器通过请求头中设置Cache-Control可以决定是否从缓存中读取资源。这也是为什么有时候点击浏览器刷新按钮和在地址栏回车,在NetWork模块中看到完全不同的结果
不推荐使用Expires,它指定的是具体的过期日期而不是秒数。因为很多服务器跟客户端存在时钟不一致的情况,所以最好还是使用Cache-Control.
服务器再验证
浏览器或代理缓存中缓存的资源过期了,并不意味着它和原始服务器上的资源有实际的差异,仅仅意味着到了要进行核对的时间了。这种情况被称为服务器再验证。
如果资源发生变化,则需要取得新的资源,并在缓存中替换旧资源。
如果资源没有发生变化,缓存只需要获取新的响应头,和一个新的过期时间,对缓存中的资源过期时间进行更新即可。
HTTP1.1推荐使用的验证方式是If-None-Match/Etag,在HTTP1.0中则使用If-Modified-Since/Last-Modified。
Etag与If-None-Match
根据实体内容生成一段hash字符串,标识资源的状态,由服务端产生。浏览器会将这串字符串传回服务器,验证资源是否已经修改,如果没有修改,过程如下:

由于Etag有服务器构造,所以在集群环境中一定要保证Etag的唯一性
If-Modified-Since与Last-Modified
这两个是HTTP1.0中用来验证资源是否过期的请求/响应头,这两个头部都是日期,验证过程与Etag类似,这里不详细介绍。使用这两个头部来验证资源是否更新时,存在以下问题:
- 有些文档资源周期性的被重写,但实际内容没有改变。此时文件元数据中会显示文件最近的修改日期与If-Modified-Since不相同,导致不必要的响应。
- 有些文档资源被修改了,但修改内容并不重要,不需要所有的缓存都更新(比如代码注释)
林秀栋的技术博客