国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

深入node.js-瀏覽器緩存機制

Stardustsky / 963人閱讀

摘要:瀏覽器緩存的使用是提高用戶體驗的一個重要途徑,通常也是優(yōu)化前端的一種重要方式。瀏覽器看到就會去讀取緩存信息并呈現(xiàn)。

瀏覽器緩存
瀏覽器緩存(Browser Caching)是為了節(jié)約網(wǎng)絡(luò)的資源加速瀏覽,瀏覽器在用戶磁盤上對最近請求過的文檔進行存儲,當訪問者再次請求這個頁面時,瀏覽器就可以從本地磁盤顯示文檔,這樣就可以加速頁面的閱覽。

瀏覽器緩存的使用是提高用戶體驗的一個重要途徑,通常也是優(yōu)化前端的一種重要方式。利用好了緩存可以加快頁面的瀏覽,降低服務(wù)器的壓力,減少網(wǎng)絡(luò)損耗等功能。

瀏覽器緩存分類

協(xié)商緩存

強制緩存

協(xié)商緩存

通過上圖分析:

客戶端向服務(wù)器請求資源

驗證標識,如果標識通過了驗證,則會響應(yīng)304,告知瀏覽器讀取緩存

如果沒有標識,或驗證沒有通過,則返回請求的資源

看到這里可能有人會有問題,標識是什么?
標識主要是用來標識請求的資源是否被修改或更新過,通過請求頭發(fā)送給服務(wù)器進行驗證。

協(xié)商緩存的標識有兩種:

ETag

Last-Modified

下面我們來講講這兩者的區(qū)別以及用法

Last-Modified

last-modified 根據(jù)詞義就可以知道表示該資源的最后修改時間。

客戶端第一次請求服務(wù)器,服務(wù)器會把該資源的最后修改時間通過響應(yīng)頭返回給客戶端

客戶端再次請求服務(wù)器的時候,如果在響應(yīng)頭中有Last-Modified字段,瀏覽器就會在請求頭中加上if-Modified-Since字段給服務(wù)器。

服務(wù)器拿到該字段的值,與該資源的最后修改時間進行對比,如果相等則說明資源沒有被修改,向客戶端返回304。

瀏覽器看到304就會去讀取緩存信息并呈現(xiàn)。

下面根據(jù)以上的幾個點,來看看代碼怎么實現(xiàn):

    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響應(yīng)頭,下次瀏覽器就會在請求頭中帶著 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");
    });
    
ETag

ETag它的流程和last-modified是一樣的,僅僅只是驗證方式不同,last-modified是取的當前請求資源的最后修改時間來作為驗證,而ETag則是對當前請求的資源做一個唯一的標識。

標識可以是一個字符串,文件的size,hash等等,只要能夠合理標識資源的唯一性并能驗證是否修改過就可以了。比如讀取文件內(nèi)容,將文件內(nèi)容轉(zhuǎn)換成一個hash值,每次接收到客戶端發(fā)送過來的時候,重新讀取文件轉(zhuǎn)成hash值,與之前的做對比,看資源是否修改過。

和Last-Modify相同,服務(wù)器在響應(yīng)頭返回一個ETag字段,那么請求的時候就會在請求頭中加入if-none-match

下面來看看代碼,代碼中我都會加入詳細的注釋:

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進行加密,相當于轉(zhuǎn)成一個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));
          // 第一次服務(wù)器返回的時候,會把文件的內(nèi)容算出來一個標識,發(fā)給客戶端
          fs.readFile(filepath, (err, content) => {
            // 客戶端看到etag之后,也會把此標識保存在客戶端,下次再訪問服務(wù)器的時候,發(fā)給服務(wù)器
            res.setHeader("Etag", etag);
            fs.createReadStream(filepath).pipe(res);
          });
        }
      });
    }
  });
});
server.listen(8000, () => {
  console.log("listen to 8000 port");
});
強制緩存

通過上圖分析:

強制緩存通過Cache-Control這個響應(yīng)頭中的max-age:60(緩存60s)來判斷緩存是否過期

如果過期了則重新向服務(wù)器請求資源

如果沒有過期,則不經(jīng)過服務(wù)器,直接讀取資源

強制緩存比較簡單,直接看一下代碼的實現(xiàn)

    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));
          // 設(shè)置緩存過期時間
          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");
    });

強制緩存就是向瀏覽器設(shè)置一個過期時間例如cache-control:max-age=60表示這是一個60秒的過期時間,60秒以內(nèi)瀏覽器都會從緩存讀取該資源,超過60秒則訪問服務(wù)器

cache-control還有另外幾個值可以設(shè)置

private 客戶端可以緩存

public 客戶端和代理服務(wù)器都可以緩存

max-age=60 緩存內(nèi)容將在60秒后失效

no-cache 需要使用對比緩存驗證數(shù)據(jù),強制向源服務(wù)器再次驗證

no-store 所有內(nèi)容都不會緩存,強制緩存和對比緩存都不會觸發(fā)

總結(jié)

理解緩存對前端開發(fā)來說十分的重要,這也是為何把這篇文章寫出來的原因,后續(xù)會繼續(xù)為大家?guī)韓ode相關(guān)的文章,如果寫錯或不好的地方希望大家指出來,如果覺得寫的還行,麻煩點個贊哈!

以下我的新個人微信公眾號,也會為大家持續(xù)提供原創(chuàng)文章,歡迎大家關(guān)注,如果用戶量足夠,會在里面為大家提供一些項目類的視頻教程,謝謝

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/108931.html

相關(guān)文章

  • 深入淺出node.js總結(jié)-模塊機制(1)

    摘要:先天就缺乏一項功能模塊通過標簽引入代碼的方式顯得雜亂無章,語言自身毫無組織和約束能力。與文件模塊區(qū)別地方在于它從內(nèi)存中加載緩存執(zhí)行結(jié)果的位置核心模塊在對象上,文件模塊在對象上未完待續(xù) javascript先天就缺乏一項功能:模塊 javasciprt 通過script標簽引入代碼的方式顯得雜亂無章,語言自身毫無組織和約束能力。人們不得不用命名空間等方式人為地約束代碼,以求達到安全和易用的...

    jifei 評論0 收藏0
  • 前端基礎(chǔ)

    摘要:談起閉包,它可是兩個核心技術(shù)之一異步基于打造前端持續(xù)集成開發(fā)環(huán)境本文將以一個標準的項目為例,完全拋棄傳統(tǒng)的前端項目開發(fā)部署方式,基于容器技術(shù)打造一個精簡的前端持續(xù)集成的開發(fā)環(huán)境。 這一次,徹底弄懂 JavaScript 執(zhí)行機制 本文的目的就是要保證你徹底弄懂javascript的執(zhí)行機制,如果讀完本文還不懂,可以揍我。 不論你是javascript新手還是老鳥,不論是面試求職,還是日...

    graf 評論0 收藏0
  • node核心特性理解

    摘要:概述本文主要介紹了我對的一些核心特性的理解,包括架構(gòu)特點機制核心模塊與簡單應(yīng)用。在此期間,主線程繼續(xù)執(zhí)行其他任務(wù)。延續(xù)了瀏覽器端單線程,只用一個主線程執(zhí)行,不斷循環(huán)遍歷事件隊列,執(zhí)行事件。 原文地址在我的博客,轉(zhuǎn)載請注明來源,謝謝! node是在前端領(lǐng)域經(jīng)??吹降脑~。node對于前端的重要性已經(jīng)不言而喻,掌握node也是作為合格的前端工程師一項基本功了。知道node、知道后端的一些東西...

    huangjinnan 評論0 收藏0
  • Node.js入門:模塊機制

    摘要:模塊載入策略的模塊分為兩類,一類為原生核心模塊,一類為文件模塊。最后傳入對象的,方法,,文件名,目錄名作為實參并執(zhí)行。在這個主文件中,可以通過方法去引入其余的模塊。以上所描述的模塊載入機制均定義在中。 CommonJS規(guī)范? 早在Netscape誕生不久后,JavaScript就一直在探索本地編程的路,Rhino是其代表產(chǎn)物。無奈那時服務(wù)端JavaScript走的路均是參考眾多服務(wù)器端...

    alanoddsoff 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<