通过最后修改时间来判断缓存是否可用
let http = require('http'); let url = require('url'); let path = require('path'); let fs = require('fs'); let mime = require('mime'); // http://localhost:8080/index.html http.createServer(function (req, res) { let { pathname } = url.parse(req.url, true); //D:\vipcode\201801\20.cache\index.html let filepath = path.join(__dirname, pathname); fs.stat(filepath, (err, stat) => { if (err) { return sendError(req, res); } else { let ifModifiedSince = req.headers['if-modified-since']; let LastModified = stat.ctime.toGMTString(); if (ifModifiedSince == LastModified) { res.writeHead(304); res.end(''); } else { return send(req, res, filepath, stat); } } }); }).listen(8080); function sendError(req, res) { res.end('Not Found'); } function send(req, res, filepath, stat) { res.setHeader('Content-Type', mime.getType(filepath)); //发给客户端之后,客户端会把此时间保存起来,下次再获取此资源的时候会把这个时间再发回服务器 res.setHeader('Last-Modified', stat.ctime.toGMTString()); fs.createReadStream(filepath).pipe(res); }
这种方式有很多缺陷
- 某些服务器不能精确得到文件的最后修改时间, 这样就无法通过最后修改时间来判断文件是否更新了
- 某些文件的修改非常频繁,在秒以下的时间内进行修改.Last-Modified只能精确到秒。
- 一些文件的最后修改时间改变了,但是内容并未改变。 我们不希望客户端认为这个文件修改了
- 如果同样的一个文件位于多个CDN服务器上的时候内容虽然一样,修改时间不一样
ETag
ETag是根据实体内容生成的一段hash字符串,可以标识资源的状态
资源发生改变时,ETag也随之发生变化。 ETag是Web服务端产生的,然后发给浏览器客户端
let http = require('http'); let url = require('url'); let path = require('path'); let fs = require('fs'); let mime = require('mime'); let crypto = require('crypto'); http.createServer(function (req, res) { let { pathname } = url.parse(req.url, true); let filepath = path.join(__dirname, pathname); fs.stat(filepath, (err, stat) => { if (err) { return sendError(req, res); } else { let ifNoneMatch = req.headers['if-none-match']; let out = fs.createReadStream(filepath); let md5 = crypto.createHash('md5'); out.on('data', function (data) { md5.update(data); }); out.on('end', function () { let etag = md5.digest('hex'); let etag = `${stat.size}`; if (ifNoneMatch == etag) { res.writeHead(304); res.end(''); } else { return send(req, res, filepath, etag); } }); } }); }).listen(8080); function sendError(req, res) { res.end('Not Found'); } function send(req, res, filepath, etag) { res.setHeader('Content-Type', mime.getType(filepath)); res.setHeader('ETag', etag); fs.createReadStream(filepath).pipe(res); }
内容版权声明:除非注明,否则皆为本站原创文章。