本文全部代码皆采用express搭建的简单服务器css
Web 缓存是能够自动保存常见文档副本的 HTTP 设备。当 Web 请求抵达缓存时, 若是本地有“已缓存的”副本,就能够从本地存储设备而不是原始服务器中提取这 个文档。(此结论来自http权威指南)html
优势:web
缺点:express
from memory cache:字面理解是从内存中,其实也是字面的含义,这个资源是直接从内存中拿到的,不会请求服务器通常已经加载过该资源且缓存在了内存当中,当关闭该页面时,此资源就被内存释放掉了,再次从新打开相同页面时不会出现from memory cache的状况浏览器
from disk cache:同上相似,此资源是从磁盘当中取出的,也是在已经在以前的某个时间加载过该资源,不会请求服务器可是此资源不会随着该页面的关闭而释放掉,由于是存在硬盘当中的,下次打开仍会from disk cache (来自:blog.csdn.net/garrettzxd/… )缓存
Expires,该值是一个GMT时间格式个字符串,浏览器进行第一次请求时,服务器会在返回头部加上Expires,下次请求,若是在这个时间以前则命中缓存,bash
app.get('/', (req, res) => {
const cssContent = path.join(__dirname, './html/index.html');
fs.readFile(cssContent, function(err, data) {
res.setHeader("Expires", new Date(Date.now() + 2592000000).toUTCString());
res.end(data);
})
});
复制代码
Cache-Control ,该值是利用max-age判断缓存的生命周期,是以秒为单位,如何在生命周期时间内,则命中缓存服务器
app.get('/', (req, res) => {
const cssContent = path.join(__dirname, './html/index.html');
fs.readFile(cssContent, function(err, data) {
res.setHeader("Cache-Control", "max-age=0");
res.end(data);
})
});
复制代码
命中缓存: 网络
Last-Modified: 表示为为实体头部部分,response返回,表示为资源的最后更新时间
If-Modified-Since:经过比较两次的时间判断,资源在请求期间是否有修改,假如没有修改,则命中协商缓存,浏览器从缓存中读取资源,若是没有命中,资源有过修改,返回新的Last-Modified时间和服务器资源app
app.get('/', (req, res) => {
const cssContent = path.join(__dirname, './html/index.html')
fs.stat(cssContent, (err, start) => {
if (req.headers['if-modified-since'] === start.mtime.toUTCString()) {
res.writeHead(304, 'Not Modified');
res.end();
} else {
fs.readFile(cssContent, function (err, data) {
let lastModified = start.mtime.toUTCString();
res.setHeader('Last-Modified', lastModified);
res.writeHead(200, 'OK');
res.end(data);
})
}
})
});
复制代码
有些状况下仅判断最后修改日期来验证资源是否有改动是不够的:
1,存在周期性重写某些资源,但资源实际包含的内容并没有变化;
2,被修改的信息并不重要,如注释等;
3,Last-Modified没法精确到毫秒,但有些资源更新频率有时会小于一秒。
ETag:为相应头部字段,表示资源内容的惟一标识,随服务器response返回;
If-None-Match: 服务器比较请求头中的If-None-Match和当前资源中的etag是否一致,来判断资源是否修改过,若是没有修改,则命中缓存,浏览器从缓存中读取资源,若是修改过,服务器会返回新的etag,并返回资源;
app.get('/home', (req, res) => {
const cssContent = path.join(__dirname, './html/index.html')
fs.stat(cssContent, (err, start) => {
let etag = md5(cssContent);
if (req.headers['if-none-match'] === etag) {
res.writeHead(304, 'Not Modified');
res.end();
} else {
fs.readFile(cssContent, function (err, data) {
res.setHeader('Etag', etag);
res.writeHead(200, 'OK');
res.end(data);
})
}
})
});
复制代码
不推荐使用 Expires 首部,它指定的是实际的过时日期而不是秒数。HTTP 设计者 后来认为,因为不少服务器的时钟都不一样步,或者不正确,因此最好仍是用剩余秒 数,而不是绝对时间来表示过时时间。
ETag解决了Last-Modified使用时可能出现的资源的时间戳变了但内容没变及若是再一秒钟之内资源变化但Last-Modified没变的问题,感受ETag更加稳妥。
补充:根据浏览器缓存策略,Expire和Cache-Control用回车、后退、F5刷新会跳过本地缓存,每次都会从服务器中获数据。