Last active
March 28, 2021 15:41
-
-
Save dailc/43b2831cc48a114ff4de4b9ff8bc7d83 to your computer and use it in GitHub Desktop.
[webvie缓存] webview和浏览器缓存机制 tags:webview,cache
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Expires,ETag,Cache-Control之间的关系 | |
### Last-Modified | |
浏览器第一次请求资源时,服务器的返回状态时`200`,内容是对应的请求资源,同时头部中会有一个`Last-Modified`属性标识,记录此文件在服务器端最后的被修改的时间,格式为: | |
``` | |
Last-Modified:Tue, 24 Feb 2009 08:01:04 GMT | |
``` | |
浏览器第二次请求此url时(如果有缓存),根据Http协议,浏览器会向服务器发送`If-Modified-Since`报头,询问该时间后文件是否有被修改过。 | |
客户端格式为: | |
``` | |
If-Modified-Since:Tue, 24 Feb 2009 08:01:04 GMT | |
``` | |
如果服务器端的资源没有变化,则会自动返回`Http 304`,内容为空,获取浏览器本地缓存,这样就节省了传输数据量。当服务器端代码发送改变或者重启时,则会重新回到第一步,在浏览器请求时写入`Last-Modified`,确保服务器有变化时,浏览器能得到最新资源 | |
tips: 如果`If-Modified-Since`的时间比服务器当前时间(当前的请求时间request_time)还晚,会认为是个非法请求 | |
### ETag | |
ETag是**被请求变量的实体标记**,ETag由服务器端生成,会随着文件的改变而改变。 | |
即服务器响应时给请求URL标记(也就是说一个请求URL对应一个ETag), | |
并通过Http响应头传给浏览器,格式为: | |
``` | |
Etag:“5d8c72a5edda8d6a:3239″ | |
``` | |
客户端的查询更新格式为: | |
``` | |
If-None-Match:“5d8c72a5edda8d6a:3239″ | |
``` | |
如果ETag没有改变,则返回状态`304`(只有`If-Modified-Since`和ETag等操作都符合才会304) | |
ETag主要用来判断URL对象是否改变,会配合`Last-Modified`等使用 | |
ETag主要用来解决`Last-Modified`无法解决的问题,比如能比`Last-Modified`更加精确的知道文件是否修改过,`Last-Modified`只能检测到秒级别,如果一秒内多次修改无法判断(原因是UNIX记录MTIME只能精确到秒),而ETag可以避免这个问题 | |
所以正常来说ETag是`Last-Modified`的精确版本。 | |
**注意** | |
分布式系统里多台机器间文件的last-modified必须保持一致,以免负载均衡到不同机器导致比对失败 | |
分布式系统尽量关闭掉Etag(每台机器生成的etag都会不一样) | |
### Expires | |
结合`Last-Modified`一起使用。用于控制请求文件的有效时间。当请求数据在有效期内浏览器从缓存获取,缓存中的数据失效或过期,才会从服务器端更新。 | |
它是`Http 1.0`的内容,声明了一个网页或URL不再被浏览器缓存的时间,一旦超过了这个时间,浏览器不管怎么样都应该重新联系服务器。如 | |
``` | |
Expires:Thu, 02 Apr 2009 05:14:08 GMT | |
``` | |
在`Http 1.0`中,如果设置了Expires,在这个时间内,浏览器不会发出新的请求,而是直接使用本地缓存。 | |
Expires 的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大,那么误差就很大,所以在HTTP 1.1版开始,使用`Cache-Control: max-age=`秒替代。 | |
每次下载新的页面时,Expires会重新计算。 | |
### Pragma | |
例如`Http 1.0`中的`Pragma:no-cache`等同于`Http 1.1`中的`Cache-Control:no-cache` | |
### Cache-Control | |
`Http 1.1`的内容,它有一个值`max-age`规定了缓存在本地的有效时间(这个是一个数字-多少秒)。 | |
`Expires =max-age + "每次下载时的当前的request时间"` | |
理论上来说,这个有效时间是和Expires的失效时间一致的,但是有时候不一定,Cache-Control的优先级要更高。 | |
(Expires是过时的,如果max-age和Expires同时存在,则被Cache-Control的max-age覆盖) | |
Cache-Control的可取值: | |
| Cache-directive| 说明 | | |
| :------------- |-------------:| | |
| public | 所有内容都将被缓存(客户端和代理服务器都可缓存) | | |
| private | 内容只缓存到私有缓存中(仅客户端可以缓存,代理服务器不可缓存) | | |
| no-cache | 必须先与服务器确认返回的响应是否被更改,然后才能使用该响应来满足后续对同一个网址的请求。因此,如果存在合适的验证令牌 (ETag),no-cache 会发起往返通信来验证缓存的响应,如果资源未被更改,可以避免下载 | | |
| no-store | 所有内容都不会被缓存到缓存或 Internet 临时文件中 | | |
| must-revalidation/proxy-revalidation | 如果缓存的内容失效,请求必须发送到服务器/代理以进行重新验证 | | |
| max-age=xxx (xxx is numeric) | 缓存的内容将在 xxx 秒后失效, 这个选项只在HTTP 1.1可用, 并如果和Last-Modified一起使用时, 优先级较高 | | |
tips: 设置了max-age时,在有效期间内,不会发起新的请求,过期后,才会重新发请求,这时候就会继续Last-Modified和Etag的验证。 | |
### 不能缓存的请求 | |
当满足以下条件时,请求无法被浏览器缓存: | |
* HTTP信息头中包含Cache-Control:no-cache,pragma:no-cache(HTTP1.0) | |
* 需要根据Cookie,认证信息等决定输入内容的动态请求是不能被缓存的 | |
* 经过HTTPS安全加密的请求(有人也经过测试发现,ie其实在头部加入Cache-Control:max-age信息,firefox在头部加入Cache-Control:Public之后,能够对HTTPS的资源进行缓存,参考[《HTTPS的七个误解》](http://www.ruanyifeng.com/blog/2011/02/seven_myths_about_https.html)) | |
* POST请求无法被缓存 | |
* HTTP响应头中不包含Last-Modified/Etag,也不包含Cache-Control/Expires的请求无法被缓存 | |
### 用户行为与缓存 | |
浏览器的缓存与不同用户行为有关,不同的机制在不同的操作下有效性不一样。如下表: | |
| 用户操作| Expires/Cache-Control | lAST-Modified/Etag | | |
| :------------- |:-------------:|-------------:| | |
| 地址栏回车 | 有效 | 有效 | | 页面链接跳转 | 有效 | 有效 | | |
| 新开窗口 | 有效 | 有效 | | |
| 前进,后退 | 有效 | 有效 | | |
| F5刷新 | 无效 | 有效 | | |
| ctrl+F5刷新 | 无效 | 无效 | | |
## 客户端缓存与服务器缓存 | |
上述提到的内容都属于客户端缓存(浏览器缓存) | |
服务器端的缓存一般是服务器为了提升速度而产生的一些临时文件,如gzip的文件,一般是放在特定的目录。 | |
## 参考 | |
* http://blog.csdn.net/eroswang/article/details/8302191 | |
* http://www.open-open.com/lib/view/open1494985360881.html | |
* http://www.cnblogs.com/zichi/p/4685822.html?tvd |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment