- 浏览器缓存
浏览器缓存是浏览器在本地磁盘对用户最近请求过的文档进行储存,当访问者在访问同一个页面时,浏览器就可以直接从本地磁盘加载文档。
当用户第一次用户发起一个静态资源请求的时候,http返回200的状态码,如果没有关闭缓存请求的话则会在返回头中返回包含last-Modified以及Etag和Expires的字段,然后将文件保存在Cache目录下;当后续请求该文件时候看缓存类型。
- 分类
强缓存:一旦资源命中强缓存, 浏览器便不会向服务器发送请求, 而是直接读取缓存。对于常规请求, 只要存在该资源的缓存, 且Cache-Control:max-age 或者Expires没有过期, 那么就能命中强缓存.
协商缓存:强缓存失效后(缓存过期后), 浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程。
三,http header中与缓存有关的key。
1》Catch-control:是http1.1的规范,表示缓存的过期时间,比Exprise优先级高(因为现在浏览器基本都是HTTP1.1版本所以catch-control有效), 它还是一个复合规则。同时在请求头和响应头都可设置,语法为: “Cache-Control : cache-directive”。
max-age:指定时间后过期,单位s
no-cache:不优先使用本地缓存,而是使用协商缓存
no-store:请求和响应都不缓存,一定不使用本地缓存,每次用户请求资源的时候,都会下载得到服务器发来的最新的资源
2》Pragma:http1.0字段, 指定缓存机制,通常设置为Pragma:no-cache。当Pragme和Exprise同时出现起作用的是Pragma。作用同Cache-Control:no-cache. 当一个no-cache请求发送给一个不遵循HTTP/1.1的服务器时, 客户端应该包含pragma指令。
2》Expries:http1.0的规范,表示缓存的过期时间, 以服务器时间为参考系。由于不能保证服务器和用户端的绝对时间保持一致,所以缓存有时可能会出现混乱的情况。
缓存时间
如果Expires, Cache-Control: max-age, 或 Cache-Control:s-maxage 都没有在响应头中出现, 并且也没有其它缓存的设置, 那么浏览器默认会采用一个启发式的算法, 通常会取响应头的Date_value - Last-Modified_value值的10%作为缓存时间。
客户端总是采用最保守的缓存策略
假设所请求资源于4月5日缓存, 且在4月12日过期.
当max-age 与 max-stale 和 min-fresh 同时使用时, 它们的设置相互之间独立生效, 最为保守的缓存策略总是有效。这意味着, 如果max-age=10 days, max-stale=2 days, min-fresh=3 days, 那么:
根据max-age的设置, 覆盖原缓存周期, 缓存资源将在4月15日失效(5+10=15);
根据max-stale的设置, 缓存过期后两天依然有效, 此时响应将返回110(Response is stale)状态码, 缓存资源将在4月14日失效(12+2=14);
根据min-fresh的设置, 至少要留有3天的新鲜期, 缓存资源将在4月9日失效(12-3=9);
因此, 4月9日后, 对于该资源的请求将重新向服务器发起验证。
协商缓存:
3》Last-modefied:资源最后一次的修改时间,Last-Modified: 星期 日期 月份 年份 时 分 秒GMT,
只能精确到秒, 因此不太适合短时间内频繁改动的资源,而且服务器端的静态资源, 通常需要编译打包, 可能出现资源内容没有改变, 而Last-Modified却改变的情况。
If-Modified-Since:缓存校验字段, 值为资源最后一次的修改时间, 即上次收到的Last-Modified值。
在用户请求到资源之后,会返回这个资源,并且在response header中返回一个last-modefied字段,这时浏览器会缓存这个资源以及最后修改的时间。接着,当用户再次请求同样的资源时,需要在请求头中添加if-modefied-since字段,服务器会和资源最近修改时间比较,如果命中,则返回304,让浏览器使用缓存的资源,否则返回一个新的资源并且在last-modefied修改为最近的资源修改时间。
4》Etag:实体标签, 服务器资源的唯一标识符。使用Etag主要是为了解决根据时间无法解决的问题:比如文件修改频繁(秒之内修改),导致根据时间无法判断是否更新;以及修改时间变了,但是内容没变(我们应该认为该文件是没变的)
If-none-Match:缓存校验字段, 结合ETag字段, 常用于判断缓存资源是否有效, 优先级比If-Modified-Since高
304:未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源
412:客户端请求信息的先决条件错误
416:客户端请求的范围无效
四,Etag和last-modefied
使用Last-Modified存在一些问题:
1)一些文件可能会周期性修改,但是内容并不修改(仅仅修改改变的修改时间),这个时候我们不希望客户端认为这个文件被修改过了,而重新请求
2)某些文件修改频繁,比如在秒以下的时间内进行修改,Last-Modified只能精确到秒,,服务器不能精确的得到文件的最后修改时间。
为了解决这些问题,添加了Etag字段来标识资源的唯一性。 服务端返回的实体里面定义一个字段Etag,这个字段的值是由某种算法计算出的唯一标识符(比如md5)
五.为什么使用缓存?
1)减少网络带宽消耗
无论对于网站运营者或者用户,带宽都代表着金钱,过多的带宽消耗,只会便宜了网络运营商。当Web缓存副本被使用时,只会产生极小的网络流量,可以有效的降低运营成本。
2)降低服务器压力
给网络资源设定有效期之后,用户可以重复使用本地的缓存,减少对源服务器的请求,间接降低服务器的压力。同时,搜索引擎的爬虫机器人也能根据过期机制降低爬取的频率,也能有效降低服务器的压力。
3)减少网络延迟,加快页面打开速度
带宽对于个人网站运营者来说是十分重要,而对于大型的互联网公司来说,可能有时因为钱多而真的不在乎。那Web缓存还有作用吗?答案是肯定的,对于最终用户,缓存的使用能够明显加快页面打开速度,达到更好的体验。