浏览器缓存小结

一. 分类

  1. 浏览器的缓存,从状态码来看一共有两种
  • 304:确认没有修改
  • 200:不发请求,直接读取缓存
  1. 从设置方式来看,有四种(暂不考虑Service Worker)
  • maxAge
  • Application Cache
  • Last-Modified/If-Modified-Since
  • Etag/If-None-Match

maxAge

  • 设置方法:
var expires = new Date();
var maxAge = 60*60*24*365;
expires.setTime(expires.getTime() + maxAge * 1000);
response.setHeader("Expires", expires.toUTCString());
response.setHeader("Cache-Control", "max-age=" + maxAge);
  • 说明:

浏览器在发送请求之前由于检测到Cache-Control和Expires(Cache-Control的优先级高于Expires,但有的浏览器不支持Cache-Control,这时采用Expires), 如果没有过期,则不会发送请求,而直接从缓存中读取文件。
Cache-Control与Expires的作用一致,都是指明当前资源的有效期,控制浏览器是否直接从浏览器缓存取数据还是重新发请求到服务器取数据。 只不过Cache-Control的选择更多,设置更细致,如果同时设置的话,其优先级高于Expires。

  • 备注:

chrome中只有通过链接跳转访问才可以,f5是不管用的,'Cache-Control' is always set to 'max-age=0′

Application Cache

因为大量的bug已经不建议使用,略

Last-Modified/If-Modified-Since

  • 设置方法
fs.stat(realPath, function (err, stat) {
    var lastModified = stat.mtime.toUTCString();
    var ifModifiedSince = "If-Modified-Since".toLowerCase();
    response.setHeader("Last-Modified", lastModified);
    if (request.headers[ifModifiedSince] && lastModified == request.headers[ifModifiedSince]) {
    response.writeHead(304, "Not Modified");
    response.end();
    }
})
  • 说明:

response 设置Last-Modified头,request便会带上If-Modified-Since头,
需要手动比较,并返回304

  • 备注

Last-Modified标注的最后修改只能精确到秒级;
有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形。

Etag/If-None-Match

  • 设置方法
var hash = crypto.createHash('md5').update(file).digest('base64');
response.setHeader("Etag", hash);
if (request.headers['if-none-match'] && request.headers['if-none-match'] === hash) {
    response.writeHead(304, "Not Modified");
    response.end();
    return;
}
  • 说明:

response设置Etag头,request便会自动带上if-none-match头;
需要手动比较,并返回304
适用于文件更新,但是内容并没有修改的情况,比如目前前端的打包。

流程图

    graph TB 
    start(浏览器请求) -->  hasAppcache{appcache?}
    hasAppcache -- YES --> 200cache[200 从缓存读取]
    hasAppcache -- NO --> ce{Cache-Control/Expires
是否有效} ce -- YES --> 200cache ce -- NO --> etag{has Etag?} etag -- YES --> ifNoMatch[向服务器请求带if-None-Match] etag -- NO --> lastModify{has Last-modified?} lastModify -- YES --> hasLastModify[向服务器请求带if-Modified-Since] lastModify == NO ==> 200server[200 从服务器读取] ifNoMatch --> match{match?} match -. YES .-> 304cache[304 从缓存读取] match == NO ==> 200server hasLastModify --> lessThenModifiedSince{lastModified
<=
ifModifiedSince?} lessThenModifiedSince -. YES .-> 304cache lessThenModifiedSince == NO ==> 200server

参考文章 https://github.com/etoah/BrowserCachePolicy

你可能感兴趣的:(浏览器缓存)