Sunshine168 / resume

My resume
3 stars 1 forks source link

Web缓存 #16

Open Sunshine168 opened 5 years ago

Sunshine168 commented 5 years ago

Web缓存是基于浏览器缓存进行的,基于HTTP协议头和HTML页面的Meta标签进行缓存控制。

如何进行缓存,一个是设置过期时间,在没有过期的时候就不会请求到服务器上——这种就是强缓存;而另外一种是带着缓存的标识询问服务器,服务器决策是否缓存——这种就是协商缓存。

从HTTP协议头上面说,可以划分有两代,第一代是HTTP 1.0 第二代则是HTTP 1.1

HTTP 1.0

1.0的时候有两个字段跟缓存相关分别是:Pragma 和 Expires;

eg: Pragma: no-cache 是控制禁用缓存实际上是表示不采取强缓存

eg: Expires: Wed, 21 Oct 2015 07:28:00 GMT 是控制缓存的有效期,也就是设置一个过期时间,但是这个过期时间是相对于服务器而言,这里就有存在一个问题,就是本地时间和服务器时间可能会存在不一致的问题

两者同时出现的时候Pragma的优先级更高

HTTP 1.1

1.1的时候采用 Cache-Control和 Last-Modified/ETag

Cache-Control 在类型上和Expires是一样的,都是设置一个过期的时间,但是与Expires不一样的是,它设置的时间是相对于浏览器的,这样就可以避免时间不一致的问题。它和Expires同时存在的时候,它的优先级更高。

Cache-Control 的取值和Expires是不一样的

对于客户端

Cache-Control: max-age=<seconds>
Cache-Control: max-stale[=<seconds>]
Cache-Control: min-fresh=<seconds>
Cache-control: no-cache 
Cache-control: no-store
Cache-control: no-transform
Cache-control: only-if-cached

对于服务端

Cache-control: must-revalidate
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: public
Cache-control: private
Cache-control: proxy-revalidate
Cache-Control: max-age=<seconds>
Cache-control: s-maxage=<seconds>

在客户端的HTTP Request Header 上和服务端 HTTP Response Header 上有一些不一样的字段,以Response public/private 为例子,前者是对于所有客户端可以缓存,后者则是对于单独客户端进行缓存。

而Cach-Control 可以通过以下方式关闭缓存

Cache-Control: no-cache, no-store, must-revalidate

分解一下

no-cache 就是不使用强缓存。

no-sotre 指的是本次请求/响应,不储存客户端或服务端的任何内容。

must-revalidate 就是缓存使用前必须验证,而且不可以使用过期资源

接下来就是Last-Modified/ETag这一对组合,通过这对组合实现协商缓存。

先说Last-Modified,当在Response中出现,在下一次对这个相同uri发起请求的时候,这个请求依然会向服务器发送过去,服务器会对比这个最后修改时间和服务器上面这个文件的修改时间,如果并没有过期则返回304,此时浏览器会从缓存中提取;如果过期了则返回新的资源。

然后为什么有了Last-Modified还需要ETag呢?

因为Last-Modified存在以下问题

1.Last-Modified 的修改时间只能精确到秒,如果在1秒内多次被修改就可能产生多个版本,导致获取的时候返回304,但是实际上资源已经产生了变化。

2.文件一定周期都会生成,但是实际上内容可能会没有变化,这个时候就不能使用缓存了

3.时间可能存在不一致的问题,例子:指服务器获取的文件修改时间可能有问题

那ETag是怎么解决以上问题的呢,ETag是根据文件内容生成的一个唯一标识,当它和Last-Modified同时使用的时候,它的优先级更高,在判断ETag相同的情况下在判断Last-Modified,最后再返回304

在上面有提到通过MeTa标签去进行缓存控制,eg:

<META HTTP-EQUIV="Pragma" CONTENT="no-cache">

但是:

部分浏览器可以支持,而且所有缓存代理服务器都不支持,因为代理不解析HTML内容本身。 ————出处


学习的链接

http://www.alloyteam.com/2012/03/web-cache-2-browser-cache/ https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cache-Control https://www.cnblogs.com/wonyun/p/5524617.html http://www.cnblogs.com/li0803/archive/2008/11/03/1324746.html