瀏覽器緩存(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相關的文章,若是寫錯或很差的地方但願你們指出來,若是以爲寫的還行,麻煩點個贊哈!
如下個人新我的微信公衆號,也會爲你們持續提供原創文章,歡迎你們關注,若是用戶量足夠,會在裏面爲你們提供一些項目類的視頻教程,謝謝