溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

js前端面試常見瀏覽器緩存強(qiáng)緩存及協(xié)商緩存的方法

發(fā)布時間:2022-06-16 14:18:20 來源:億速云 閱讀:760 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“js前端面試常見瀏覽器緩存強(qiáng)緩存及協(xié)商緩存的方法”的相關(guān)知識,小編通過實(shí)際案例向大家展示操作過程,操作方法簡單快捷,實(shí)用性強(qiáng),希望這篇“js前端面試常見瀏覽器緩存強(qiáng)緩存及協(xié)商緩存的方法”文章能幫助大家解決問題。

前言

瀏覽器緩存

瀏覽器緩存是瀏覽器在本地磁盤對用戶最近請求過的文檔進(jìn)行存儲,當(dāng)訪問者再次訪問同一頁面時,瀏覽器就可以直接從本地磁盤加載文檔。 瀏覽器緩存主要分為強(qiáng)緩存(也稱本地緩存)和協(xié)商緩存(也稱弱緩存)。

強(qiáng)緩存

當(dāng)請求資源的時,如果是之前請求過的并使用強(qiáng)緩存,那么在過期時間內(nèi)將不會發(fā)送本次請求向服務(wù)器獲取資源,而是直接從瀏覽器緩存中獲?。ú还苜Y源是否改動)。過期了將重新從服務(wù)器獲取,并再次強(qiáng)緩存。

協(xié)商緩存

當(dāng)請求資源時,如果是之前請求過的并使用協(xié)商緩存,還是發(fā)送請求到服務(wù)器,服務(wù)器通過邏輯判斷確認(rèn)資源沒有修改返回304狀態(tài)碼,那么本次的資源則是從緩存中獲?。蝗绻?jīng)過判斷確認(rèn)資源被修改過,則重新發(fā)送資源到客戶端,并且客戶端更新緩存。

判斷資源是否修改有兩種標(biāo)準(zhǔn),一種是判斷最后修改時間是否變了(確實(shí)是修改了,但資源的內(nèi)容可以沒有變),另一種是判斷資源的內(nèi)容是否修改。

使用緩存有下面的優(yōu)點(diǎn):

  • 減少冗余的數(shù)據(jù)傳輸

  • 減少服務(wù)器負(fù)擔(dān)

  • 加快客戶端加載網(wǎng)頁的速度

搭建環(huán)境

  • 創(chuàng)建文件夾app,并在下創(chuàng)建app.js 和 fs/a.txt(里面隨便寫東西)

js前端面試常見瀏覽器緩存強(qiáng)緩存及協(xié)商緩存的方法

我們使用node+koa2來搭建我們需要的環(huán)境,安裝koa、安裝路由

npm install koa --save
npm install koa-router --save

app.js

var Koa = require('koa');
var app = new Koa();
var Router = require('koa-router')();
const fs = require('fs')
Router.get("/", async (ctx) => {
    ctx.body = "ok"
})
app
    .use(Router.routes())   	//啟動路由
    .use(Router.allowedMethods());
app.listen(3000);

啟動服務(wù)器,網(wǎng)頁輸入網(wǎng)址127.0.0.1:3000,環(huán)境搭建成功

js前端面試常見瀏覽器緩存強(qiáng)緩存及協(xié)商緩存的方法

強(qiáng)緩存

強(qiáng)緩存是利用http頭中的Expires和Cache-Control兩個字段來控制的,Expires是http1.0的規(guī)范,Cache-Control是在http1.1中出現(xiàn)的,我們這里使用Cache-Control示范。

Cache-Control有一些常設(shè)置的值

  • private:僅瀏覽器可以緩存(默認(rèn)值);

  • public:瀏覽器和代理服務(wù)器都可以緩存;

  • max-age=xxx:過期時間單位秒;

  • no-cache:不進(jìn)行強(qiáng)緩存;

  • no-store:不強(qiáng)緩存,也不協(xié)商緩存)

將上面 / 路由的代碼改為

Router.get('/', async (ctx) => {
    const getResource = () => {
        return new Promise((res) => {
            fs.readFile("./fs/a.txt", (err, data) => {
                if (err) {
                    return;
                }
                res(data)
            })
        })
    }
    ctx.set('Cache-Control', 'max-age=10')  //設(shè)置強(qiáng)緩存,過期時間為10秒
    ctx.body = await getResource(); 
})

將測試搭建環(huán)境頁面關(guān)閉,重新打開網(wǎng)頁訪問127.0.0.1:3000

前端頁面響應(yīng)頭多了Cache-Control這個字段,且10s內(nèi)都走本地緩存,不會去請求服務(wù)端

js前端面試常見瀏覽器緩存強(qiáng)緩存及協(xié)商緩存的方法

在過期時間內(nèi)再次請求資源,就可以看到這次請求并沒有經(jīng)過服務(wù)器

js前端面試常見瀏覽器緩存強(qiáng)緩存及協(xié)商緩存的方法

協(xié)商緩存

主要涉及到兩組header字段:Etag和If-None-Match、Last-Modified和if-modified-since。

Etag和If-None-Match

Etag/If-None-Match返回的是一個校驗(yàn)碼。ETag可以保證每一個資源是唯一的,資源變化都會導(dǎo)致ETag變化。服務(wù)器根據(jù)瀏覽器上送的If-None-Match值來判斷是否命中緩存。 當(dāng)服務(wù)器返回304 Not Modified的響應(yīng)時,由于ETag重新生成過,response header中還會把這個ETag返回,即使這個ETag跟之前的沒有變化。

Last-Modify和if-modified-since

瀏覽器第一次請求一個資源的時候,服務(wù)器返回的header中會加上Last-Modify,Last-Modify是一個時間標(biāo)識該資源的最后修改時間,例如Last-Modify: Thu,31 Dec 2037 23:59:59 GMT。

當(dāng)瀏覽器再次請求該資源時,request的請求頭中會包含 if-modified-since,該值為緩存之前返回的Last-Modify。服務(wù)器收到if-modified-since后,根據(jù)資源的最后修改時間判斷是否命中緩存。

如果命中緩存,則返回304,并且不會返回資源內(nèi)容,并且不會返回Last-Modify。

樣例我們使用Last-Modify和if-modified-since來實(shí)現(xiàn)。對于Etag和If-None-Match的實(shí)現(xiàn),讀取資源內(nèi)容,轉(zhuǎn)成hash值,然后跟Last-Modify和if-modified-since的實(shí)現(xiàn)差不多了,同一個道理。

新添加一個路由器

Router.get('/pp', async (ctx) => {
    const ifModifiedSince = ctx.request.header['if-modified-since'];
    const getResource = () => {
        return new Promise((res) => {
            fs.stat("./fs/a.txt", (err, stats) => {
                if (err) {
                    console.log(err);
                }
                res(stats)
            })
        })
    }
    let resource = await getResource();
    // atime	Access Time	訪問時間	
    // 最后一次訪問文件(讀取或執(zhí)行)的時間
    // ctime	Change Time	變化時間	
    // 最后一次改變文件(屬性或權(quán)限)或者目錄(屬性或權(quán)限)的時間
    // mtime	Modify Time	修改時間	
    // 最后一次修改文件(內(nèi)容)或者目錄(內(nèi)容)的時間
    if (ifModifiedSince === resource.mtime.toGMTString()) { //把具體的日期轉(zhuǎn)換為(根據(jù) GMT)字符串
        ctx.status = 304;
    }
    ctx.set('Last-Modified', resource.mtime.toGMTString());
    ctx.body = resource
})

關(guān)閉頁面,重新打開網(wǎng)頁訪問127.0.0.1:3000/pp

第一次請求,是沒有if-modified-since字段的

js前端面試常見瀏覽器緩存強(qiáng)緩存及協(xié)商緩存的方法

第二次請求,沒有修改資源,返回狀態(tài)碼304,從緩存獲取資源

js前端面試常見瀏覽器緩存強(qiáng)緩存及協(xié)商緩存的方法

修改a.txt文件里內(nèi)容時,重新請求服務(wù)器

js前端面試常見瀏覽器緩存強(qiáng)緩存及協(xié)商緩存的方法

關(guān)于“js前端面試常見瀏覽器緩存強(qiáng)緩存及協(xié)商緩存的方法”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識,可以關(guān)注億速云行業(yè)資訊頻道,小編每天都會為大家更新不同的知識點(diǎn)。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

js
AI