浏览器缓存(Browser Caching)是为了节约网络的资源加速浏览,浏览器在用户磁盘上对最近请求过的文档进行存储,当访问者再次请求这个页面时,浏览器就能够从本地磁盘显示文档,这样就能够加速页面的阅览。
浏览器缓存的使用是提升用户体验的一个重要途径,一般也是优化前端的一种重要方式。利用好了缓存能够加快页面的浏览,下降服务器的压力,减小网络损耗等功能。前端
经过上图分析:node
看到这里可能有人会有问题,标识是什么?
标识主要是用来标识请求的资源是否被修改或更新过,经过请求头发送给服务器进行验证。浏览器
协商缓存的标识有两种:缓存
下面咱们来说讲这二者的区别以及用法服务器
last-modified 根据词义就能够知道表示该资源的最后修改时间。微信
下面根据以上的几个点,来看看代码怎么实现:网络
const http = require('http'); const url = require('url'); const path = require('path'); const fs = require('fs'); const mime = require('mime'); const server = http.createServer((req, res) => { // 获取文件名 const { pathname } = url.parse(req.url, true); // 获取文件路径 const filepath = path.join(__dirname, pathname); /** * 判断文件是否存在 */ fs.stat(filepath, (err, stat) => { if (err) { res.end('not found'); } else { // 获取if-modified-since这个请求头 const ifModifiedSince = req.headers['if-modified-since']; // 获取资源最后修改时间 let lastModified = stat.ctime.toGMTString(); // 验证资源是否被修改过,若是相同则返回304让浏览器读取缓存 if (ifModifiedSince === lastModified) { res.writeHead(304); res.end(); } // 缓存没有经过则返回资源,并加上 last-modified响应头,下次浏览器就会在请求头中带着 if-modified-since else { res.setHeader('Content-Type', mime.getType(filepath)); res.setHeader('Last-Modified', stat.ctime.toGMTString()); fs.createReadStream(filepath).pipe(res); } } }); }); server.listen(8000, () => { console.log('listen to 8000 port'); });
下面来看看代码,代码中我都会加入详细的注释:优化
const http = require('http'); const url = require('url'); const path = require('path'); const fs = require('fs'); const mime = require('mime'); const crypto = require('crypto'); const server = 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 readStream = fs.createReadStream(filepath); let md5 = crypto.createHash('md5'); // 经过流的方式读取文件而且经过md5进行加密,至关于转成一个hash字符串做为etag的值 readStream.on('data', function(data) { md5.update(data); }); readStream.on('end', function() { let etag = md5.digest('hex'); // 验证etag,判断资源是否被修改过,若是没有则返回304 if (ifNoneMatch === etag) { res.writeHead(304); res.end(); } else { res.setHeader('Content-Type', mime.getType(filepath)); // 第一次服务器返回的时候,会把文件的内容算出来一个标识,发给客户端 fs.readFile(filepath, (err, content) => { // 客户端看到etag以后,也会把此标识保存在客户端,下次再访问服务器的时候,发给服务器 res.setHeader('Etag', etag); fs.createReadStream(filepath).pipe(res); }); } }); } }); }); server.listen(8000, () => { console.log('listen to 8000 port'); });
经过上图分析:ui
强制缓存比较简单,直接看一下代码的实现加密
const http = require('http'); const url = require('url'); const path = require('path'); const fs = require('fs'); const mime = require('mime'); const server = 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) { res.setHeader('Content-Type', mime.getType(filepath)); // 设置缓存过时时间 res.setHeader('Cache-Control', 'max-age=100'); fs.createReadStream(filepath).pipe(res); } else { return send(req, res, filepath); } }); }); server.listen(8000, () => { console.log('listen to port 8000'); });
强制缓存就是向浏览器设置一个过时时间例如cache-control:max-age=60表示这是一个60秒的过时时间,60秒之内浏览器都会从缓存读取该资源,超过60秒则访问服务器
cache-control还有另外几个值能够设置
理解缓存对前端开发来讲十分的重要,这也是为什么把这篇文章写出来的缘由,后续会继续为你们带来node相关的文章,若是写错或很差的地方但愿你们指出来,若是以为写的还行,麻烦点个赞哈!
如下个人新我的微信公众号,也会为你们持续提供原创文章,欢迎你们关注,若是用户量足够,会在里面为你们提供一些项目类的视频教程,谢谢