浏览器缓存小结

一. 分类

  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。javascript

  • 备注:

chrome中只有经过连接跳转访问才能够,f5是无论用的,'Cache-Control' is always set to 'max-age=0′前端

Application Cache

由于大量的bug已经不建议使用,略java

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头,
须要手动比较,并返回304git

  • 备注

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

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
适用于文件更新,可是内容并无修改的状况,好比目前前端的打包。chrome

流程图

graph TB 
    start(浏览器请求) -->  hasAppcache{appcache?}
    hasAppcache -- YES --> 200cache[200 从缓存读取]
    hasAppcache -- NO --> ce{Cache-Control/Expires</br>是否有效}
    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</br><=</br>ifModifiedSince?}
    lessThenModifiedSince -. YES .-> 304cache
    lessThenModifiedSince == NO ==> 200server

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

相关文章
相关标签/搜索