`

http协议:Web前端-HTTP Cache-control/浏览器缓存(转)

    博客分类:
  • web
阅读更多

HTTP协议分别在 1.0 / 1.1 两个时代推出了 Expires / Cache-control 两种cache策略,这里我们无需了解全部的细节,无需记住整个RFC内容,但是当我们需要使用HTTP cache策略时,我们需要注意以下细节:
Expires 是HTTP 1.0 那个时代的东西了,目前来看,可以不使用了,因为HTTP 1.0 的user agent占有率在 0.1% 以下(我们主要面向的web浏览器均默认使用HTTP 1.1),Cache-control 是 HTTP 1.1 的新特性,也是我们主要做文章使用cache策略的工具.
Cache策略:
#1 保鲜期only
这个是最最基础的一种策略,只需要在响应头中设定:
Cache-control: max-age=[secs]
[secs]是cache在客户端存活的秒数,例如 Cache-control: max-age=1800 表明cache的时间是半小时,只使用这样一个声明就可以使浏览器能够将这个HTTP响应的内容写入临时目录做cache.
这里是简要过程:

I(1)浏览器第一次请求资源http://test.qq.com/test.cgi
(2)查询临时文件目录发现无cache存储,遂发出请求到web server
(3)web server响应资源,并设定Cache-control:max-age=300
(4)浏览器收到响应将资源呈献给用户的同时,在临时文件目录以"http://test.qq.com/test.cgi"为key缓存这个响应

---5分钟内---
II(1)浏览器再一次请求资源http://test.qq.com/test.cgi
(2)查询临时文件目录发现存在cache存储,检查保鲜期max-age,还未过期,则直接读取之,响应给用户

---5分钟后---
III(1)浏览器再一次请求资源http://test.qq.com/test.cgi
(2)查询临时文件目录发现存在cache存储,检查保鲜期max-age,已经过期,则发请求到web server
#2 保鲜期 + 最后修改时间验证
这里的要素是,在给出保鲜期的同时,给出一个资源的验证方式:
Last-Modified: [UTC time]
[UTC time]标示这个响应资源的最后修改时间,例如 Last-Modified: Mon, 06 Jul 2009 09:21:48 GMT
这个响应头只有配合Cache-control的时候才有实际价值,只是声明校验资源的方式,并不能影响资源的保鲜期时长

利用资源的可校验性,我们可以实现在cache的资源超过保鲜期浏览器再次请求时的304响应,令浏览器再次使用之前的cache

这里是简要过程:
I(1)同#1中I (1)
(2)同#1中I (2)
(3)web server响应资源,并设定
Cache-control:max-age=300
Last-Modified: Mon, 06 Jul 2009 09:21:48 GMT
(4)同#1中I (4)

---5分钟内---
(同#1中II)

<iframe id="aswift_1" style="margin: 0px; padding: 0px; border-width: 0px; vertical-align: baseline; left: 0px; position: absolute; top: 0px;" name="aswift_1" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="468" height="60"></iframe>

---5分钟后---
III(1)浏览器再一次请求资源http://test.qq.com/test.cgi
(2) 查询临时文件目录发现存在cache存储,检查保鲜期max-age,已经过期发现资源具有Last-Modified声明,则为请求带上头 If-Modified-Since: Mon, 06 Jul 2009 09:21:48 GMT 发送请求到web server
(3)web server收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对,若最后修改时间较新,说明资源又被改动过,则响应整片资源内容,HTTP 200 (需要整块内容写为包体).若最后修改时间较旧,说明资源无新修改,则响应HTTP 304 (无需包体),告知浏览器继续使用所保存的cache,(这里当然也可以根据自己的需要决定是200还是304,我们的CGI毕竟是一种原始的实现)

#3 保鲜期 + 自定义标识验证
这里的要素是,在给出保鲜期的同时,给出另一种资源的验证方式:
ETag: [custom flag]
[custom flag]标示这个响应资源的由开发者自己确定的签名验证标识,例如 ETag: "abcdefg",这个响应头只有配合Cache-control的时候才有实际价值,是声明校验资源的方式

ETag的使用为我们实现304响应提供了更多的灵活性,我们可以抛开必须将验证转化成时间格式的限制

这里是简要过程:
I(1)同#1中I (1)
(2)同#1中I (2)
(3)web server响应资源,并设定
Cache-control:max-age=300
ETag: "abcdefg"
(4)同#1中I (4)

---5分钟内---
(同#1中II)

---5分钟后---
III(1)浏览器再一次请求资源http://test.qq.com/test.cgi
(2)查询临时文件目录发现存在cache存储,检查保鲜期max-age,已经过期发现资源具有ETag声明,则为请求带上头 If-None-Match: "abcdefg",发送请求到web server
(3)web server收到请求后发现有头If-None-Match 则与被请求资源的相应校验串进行比对,Etag可以是一个版本号,可以是短时间戳,可以是资源校验和(强烈不推荐使用),或者干脆是一个常量(可以干脆拿来做容错)
If-None-Match发来的串与我们的自有值比对,根据我们自己的任何策略算法,可以自由决定如何返回浏览器,304或200
这里有一个使用ETag来做容错的例子(应用列表目前在使用):
(1)我们的每次正常返回都是200
Cache-control: max-age=1800
ETag: "anything"
这里anything是个常量,我们只用来告诉浏览器,cache过期要发带If-None-Match的请求过来
(2) 这样来自客户端的一大部分请求基本上都会带上If-None-Match头,我们的CGI据此可以知道这个请求的客户端是否有cache,此时如果 CGI联系server失败,那么可以直接返回304,驱使客户端使用上一次cache的正确结果,且更新保鲜期max-age为300秒,这样我们实现 了一个基于HTTP cache的容错,如果我们的资源还能实现一套时间戳存储的话,那么我们可以在正常情况下也实现校验后的304,从而节省流量

这里还有一个比较惨的教训,国内www上都没有文献记载,全球业界也只有一点文献可以找到:
IE6 在资源有gzip压缩同时有ETag头时,cache后再次发请求不会带If-None-Match头!!!

分享到:
评论

相关推荐

    springmodules-cache.xsd&springmodules-ehcache.xsd.rar

    解决web.xml中 &lt;page-encoding&gt;UTF-8&lt;/page-encoding&gt;报错。错误提示: cvc-complex-type.2.4.a: Invalid content was found starting with element 'page-encoding'. One of '{"http:// java.sun....

    opensuse12.3版本gcc安装资源(32和64位)

    opensuse12.3版本gcc安装资源(32和64位),将var.cache.zypp.raw文件夹下资源直接拷贝到opensuselinux环境下的/var/cache/zypp/raw下,执行安装即可 linux-d9x7:/var/cache/zypp/raw # pwd /var/cache/zypp/raw ...

    cache-api-1.1.1-API文档-中文版.zip

    赠送jar包:cache-api-1.1.1.jar; 赠送原API文档:cache-api-1.1.1-javadoc.jar; 赠送源代码:cache-api-1.1.1-sources.jar; 赠送Maven依赖信息文件:cache-api-1.1.1.pom; 包含翻译后的API文档:cache-api-...

    npm-proxy-cache, http/https缓存代理使用npm实用程序.zip

    npm-proxy-cache, http/https缓存代理使用npm实用程序 npm-proxy-cache 使用 npm 实用工具的http/https缓存代理。 这是收费而不是反向代理。如果你遇到巨大的网络延迟/延迟问题,你可能会发现这个工具很有用。 其他...

    Microsoft Edge Insider 安装包提取,可离线安装

    Cache-Control: no-cache Connection: Keep-Alive Pragma: no-cache User-Agent: Microsoft Edge Update/1.3.107.15;winhttp X-Old-UID: age=7; cnt=1 X-Last-HR: 0x0 X-Last-HTTP-Status-Code: 0 X-Retry-Count: 0 ...

    lfscache:LFS缓存是一个缓存Git LFS代理

    lfs快取lfs-cache是服务器的缓存代理。用法码头工人$ docker run --name lfscache --rm -d -v /my/cache/dir/lfs:/lfs saracen/lfscache:latest --url github....

    tslib-master.zip

    #./configure --host=arm-hisiv400-linux --cache-file=arm-hisiv400-linux.cache --enable-inputapi=no --prefix=$(pwd)/arm-hisiv400-linux-target ./configure --host=arm-hisiv400-linux-gnueabi --cache-file=...

    shiro-cache-1.4.0-API文档-中英对照版.zip

    赠送jar包:shiro-cache-1.4.0.jar; 赠送原API文档:shiro-cache-1.4.0-javadoc.jar; 赠送源代码:shiro-cache-1.4.0-sources.jar; 赠送Maven依赖信息文件:shiro-cache-1.4.0.pom; 包含翻译后的API文档:shiro-...

    维酷koa博客框架version0.4.3koajsblog.zip

    "koa-static-cache": "",//静态文件缓存加载 "co":"",//异步流 "co-fs": "", //文件流 "co-body": "",//post JSON模块 "co-views": "",//视图模块 "koa-compose":"",//函数合并执行 "swig": "",//模版引擎 "xss":"",...

    axios-request-cache:前端数据接口缓存

    这里讲的前端缓存是指前端对接口数据的缓存处理,而不是通过 HTTP(s)缓存 需要配合axios使用 安装 通过npm安装: npm install axios-request-cache --save 通过yarn安装: yarn add axios-request-cache 参数说明 ...

    webext-storage-cache:WebExtensions模块

    webext-storage-cache WebExtensions模块:具有到期时间的类似地图的承诺缓存存储。 Chrome和Firefox。 该模块适用于内容脚本,背景页面和选项页面。 安装 您可以下载并将其包含在manifest.json 。 或使用npm : ...

    web-cache-warmer:网络缓存预热器

    网络缓存预热器web-cache-warmer是一个用于预热网站和 FTP 缓存的脚本。 它将使用您指定的用户代理字符串下载您指定的 URL。 它还可以递归抓取,并下载其中包含的 URL。 有关更多文档,请参阅。安装验证您是否安装了...

    react-native-http-cache2:RN http 缓存管理 原 repo 为 react-native-http-cache 由于不在维护, 对新版本 RN 不在支持, 故新建一个

    对fetch / XMLHttpRequest和ImageView进行本机http缓存控制 的iOS 安卓安装$ npm install react-native-http-cache2 --saveiOS:在您的XCode项目中进行链接从node_modules/react-native-http-cache2/ios文件夹中链接...

    browser-module-cache:使用 level.js 缓存 browserify-cdn 模块

    浏览器模块缓存使用缓存 browserify-cdn 模块npm install browser-module-cache用法 var createCache = require ( 'browser-module-cache' )初始化创建缓存(选项) var cache = createCache ( { name : 'browser-...

    cache-control:可以在上次更新时间方面覆盖的缓存控制

    安装composer require nomenjanahary/cache-control配置storage_cache_control : exclude_status : - " 5xx " - " 4xx " default_cache : maxAge : 3600 public : true # merge, replace override_strategy : merge ...

    cache-api-1.1.1-API文档-中英对照版.zip

    赠送jar包:cache-api-1.1.1.jar; 赠送原API文档:cache-api-1.1.1-javadoc.jar; 赠送源代码:cache-api-1.1.1-sources.jar; 赠送Maven依赖信息文件:cache-api-1.1.1.pom; 包含翻译后的API文档:cache-api-...

    shiro-cache-1.4.0-API文档-中文版.zip

    赠送jar包:shiro-cache-1.4.0.jar; 赠送原API文档:shiro-cache-1.4.0-javadoc.jar; 赠送源代码:shiro-cache-1.4.0-sources.jar; 赠送Maven依赖信息文件:shiro-cache-1.4.0.pom; 包含翻译后的API文档:shiro-...

    web-storage-cache.js

    还在烦恼JS前端,或者移动端缓存使用什么来储存吗。可以使用web-storage-cache.js,进行数据缓存。

    ubuntu中总是提示无法获得锁 (资源暂时不可用) 进程被占用 解决办法

    E: 无法获取 dpkg 前端锁 (/var/lib/dpkg/lock-frontend),是否有其他进程正占用它? root@klw-HP-Z400-Workstation:/# sudo rm /var/lib/dpkg/lock rm: 无法删除'/var/lib/dpkg/lock': 没有那个文件或目录 root@...

    Linux(CentOS6.5) 安装Oracle11g所需安装依赖包Packages(64bit)

    CentOS6.5安装Oracle11g时所需要的所有系统安装依赖包,包含以下rpm包 pdksh-5.2.14-37.el5_8.1.x86_64.rpm compat-libstdc++-33-3.2.3-69.el6.x86_64.rpm elfutils-libelf-devel-0.152-1.el6.x86_64.rpm ...

Global site tag (gtag.js) - Google Analytics