本程式碼實驗室說明如何變更 HTTP 快取標頭,這些標頭是由執行 Express 服務架構、以 Node.js 為基礎的網路伺服器傳回。此外,本課程也會說明如何使用 Chrome 開發人員工具中的「網路」面板,確認預期的快取行為是否確實套用。
熟悉範例專案
您在範例專案中會用到的重要檔案如下:
server.js包含提供網頁應用程式內容的 Node.js 程式碼。並使用 Express 處理 HTTP 要求和回應。具體來說,express.static()是用來提供公開目錄中的所有本機檔案,因此serve-static說明文件會派上用場。public/index.html是網頁應用程式的 HTML。與大多數 HTML 檔案一樣,其網址不含任何版本資訊。public/app.15261a07.js和public/style.391484cf.css是網頁應用程式的 JavaScript 和 CSS 資產。這些檔案的網址中都包含雜湊,與其內容相對應。index.html負責追蹤要載入的特定版本網址。
設定 HTML 的快取標頭
回應不含版本資訊的網址要求時,請務必在回應訊息中加入 Cache-Control: no-cache。此外,建議您設定兩個額外回應標頭的其中一個:Last-Modified 或 ETag。index.html 屬於這個類別。您可以將這個過程分為兩個步驟。
首先,Last-Modified 和 ETag 標頭是由 etag 和 lastModified 設定選項控制。這兩個選項實際上預設為所有 HTTP 回應的 true,因此在目前的設定中,您「不必」選擇加入即可取得該行為。不過,您還是可以在設定中明確指定。
其次,您必須能夠新增 Cache-Control: no-cache 標頭,但僅限 HTML 文件 (在本例中為 index.html)。如要依條件設定這個標頭,最簡單的方法是編寫自訂 setHeaders function,並在其中檢查傳入的要求是否為 HTML 文件。
server.js 中的靜態供應設定一開始如下所示:
app.use(express.static('public'));
- 完成上述變更後,結果應如下所示:
app.use(express.static('public', {
etag: true, // Just being explicit about the default.
lastModified: true, // Just being explicit about the default.
setHeaders: (res, path) => {
if (path.endsWith('.html')) {
// All of the project's HTML files end in .html
res.setHeader('Cache-Control', 'no-cache');
}
},
}));
為版本化網址設定快取標頭
回應包含「fingerprint」或版本資訊,且內容不應變更的網址要求時,請在回應中加入 Cache-Control: max-age=31536000。app.15261a07.js 和 style.391484cf.css 屬於這個類別。
您可以根據上一步使用的 setHeaders function,新增額外邏輯來檢查特定要求是否為版本化網址,如果是,則新增 Cache-Control:
max-age=31536000 標頭。
最穩健的做法是使用規則運算式,查看要求的資產是否符合您知道雜湊值所屬的特定模式。在這個範例專案中,一律是由 0 到 9 的數字和 a 到 f 的小寫字母 (即十六進位字元) 組成的八個字元。雜湊兩側一律會以 . 字元分隔。
符合這些一般規則的規則運算式可以表示為 new RegExp('\\.[0-9a-f]{8}\\.')。
- 修改
setHeaders函式,如下所示:
app.use(express.static('public', {
etag: true, // Just being explicit about the default.
lastModified: true, // Just being explicit about the default.
setHeaders: (res, path) => {
const hashRegExp = new RegExp('\\.[0-9a-f]{8}\\.');
if (path.endsWith('.html')) {
// All of the project's HTML files end in .html
res.setHeader('Cache-Control', 'no-cache');
} else if (hashRegExp.test(path)) {
// If the RegExp matched, then we have a versioned URL.
res.setHeader('Cache-Control', 'max-age=31536000');
}
},
}));
使用開發人員工具確認新行為
修改靜態檔案伺服器後,您可以開啟開發人員工具的「網路」面板,預覽實際運作的應用程式,確認是否已設定正確的標頭。
- 在欄標題上按一下滑鼠右鍵,即可自訂「網路」面板中顯示的資料欄,納入最相關的資訊:

這裡需要注意的資料欄是 Name、Status、Cache-Control、ETag 和 Last-Modified。
- 在開發人員工具中開啟「網路」面板,然後重新整理網頁。
頁面載入後,您應該會在「網路」面板中看到類似下方的項目:

第一列是您前往的 HTML 文件。這項作業可透過 Cache-Control: no-cache 妥善處理。該要求的 HTTP 回應狀態為 304。這表示瀏覽器知道不要立即使用快取的 HTML,而是向網路伺服器發出 HTTP 要求,使用 Last-Modified 和 ETag 資訊查看快取中的 HTML 是否有任何更新。HTTP 304 回應表示 HTML 未更新。
接下來兩列是 JavaScript 和 CSS 資產的版本。您應該會看到這些網頁透過 Cache-Control: max-age=31536000 提供,且每個網頁的 HTTP 狀態都是 200。由於使用的設定,系統不會向 Node.js 伺服器發出實際要求,點選該項目會顯示其他詳細資料,包括回應來自「(從磁碟快取)」。

ETag 和 Last-Modified 欄的實際值並不重要。重要的是確認這些值是否已設定。
總結
完成本程式碼實驗室的步驟後,您現在已熟悉如何使用 Express,在以 Node.js 為基礎的網路伺服器中設定 HTTP 回應標頭,以最佳方式使用 HTTP 快取。您也知道如何透過 Chrome 開發人員工具的「網路」面板,確認是否使用預期的快取行為。