附加一個版本,指示緩存的舊版本的靜態檔是最新的,以便不使用

頁面創建日期 :

前一段很長,所以如果你只看程式,請跳過它。

環境

Visual Studio
  • Visual Studio 2019
ASP.NET Core
  • 3.1 (Razor 頁面, MVC)

關於快取網頁上的檔

存取網頁時,除了 HTML 外,.js檔案 (Javascript) 、.css 檔案(樣式表)和圖像檔將下載到用戶端以查看和運行。 但是,一些圖像檔可能很大,每次下載都會增加成本。 此外,對於.js和.css檔,同一檔通常也用於其他頁面,因此每次下載這些檔都沒有任何意義。 這些檔可能會在下載後臨時存儲在瀏覽器中。 這就是 所謂的緩存。

例如,如果快取了檔,則當您存取同一頁面時,HTML 會從 Web 伺服器下載。 對於其他檔,如果快取可用,則使用本地存儲的檔案進行查看和運行,而無需下載。 這會降低伺服器負載,並允許用戶端快速查看頁面,而無需消耗通信頻寬。

緩存引起的問題

伺服器上的檔案和快取的檔案是否相同通常取決於 HTML 中描述的檔案路徑。 如果文件路徑相同,則通常使用快取的檔案。 (可能還有其他條件,但檔案路徑是確定的)

下面是檔路徑的示例。 href 和 src 屬性參數適用。

<!-- スタイルシート (.css) -->
<link rel="stylesheet" href="/css/site.css" />

<!-- 画像ファイル -->
<img src="/image/sample.png" alt="サンプル画像" />

<!-- JavaScript (.js) -->
<script src="/js/site.js"></script>

但是,如果發生此行為,這可能是一個問題。

例如,如果使用者在首次訪問時具有版本 1 的 JavaScript 檔,則緩存版本 1 的 JavaScript 檔。 然後,在伺服器端發佈版本 2 的 JavaScript 檔。 如果使用者訪問同一頁面時 JavaScript 檔具有相同的路徑,則可能會使用快取的版本 1 Javascript 檔案,而不下載伺服器版本 2 的 JavaScript 檔。 這可能會導致發佈者無意中出現故障。

這一次,在用戶的反應之一,"嘗試刪除緩存",我認為經常看到,因為這可能是原因。

伺服器端緩存問題解決方法

如前所述,是否使用緩存的檔在很大程度上取決於檔路徑 (URL)。

因此,在更新檔時,可以重新命名檔以強制下載新檔。

例如,如果版本 1 檔是

<link rel="stylesheet" href="/css/site.css" />

更新檔的版本 2 是

<link rel="stylesheet" href="/css/site2.css" />

這將在用戶端.css使用 site2 檔。

但是,手動執行此操作可能會給更改路徑或更改物理檔名造成麻煩和錯誤。

將查詢參數附加到文件路徑

Web 的工作方式允許您在路徑後面添加鍵和值組合的查詢參數。 即使物理檔相同,如果查詢參數不同,用戶端緩存機制也會將該檔識別為單獨的檔。 查詢參數是附加的,如果沒有用途,則沒有任何意義。

查詢參數可以以以下格式附加到路徑:

<!-- クエリパラメータなし -->
<link rel="stylesheet" href="/css/site.css" />

<!-- クエリパラメータあり -->
<link rel="stylesheet" href="/css/site.css?key=value" />

此機制要求更改路徑,但不需要重新命名物理檔。

以程式設計方式自動新增查詢參數(一個壞範例)

通過以程式設計方式自動附加該查詢參數, 即使更改了靜態檔,也無需手動更改文件路徑。

一個簡單的範例是,當使用者訪問網頁時,將當前時間添加到查詢參數。 這很容易,因為我認為任何程式設計語言都可以在一行中編寫。 我認為生成示例如下所示。

<link rel="stylesheet" href="/css/site.css?20210223120000" />

但是,這樣做的缺點是緩存沒有好處。 每次訪問網頁時,路徑都會更改,因此儘管該檔與上次相同 它被視為單獨的檔,因此每次從伺服器下載 CSS 檔。 舊版本的檔將永遠不會使用,但它只是與不使用緩存功能相同。

ASP.NET Core 中的查詢參數附加進行檔版本控制

雖然不再有前置 ASP.NET 但核心是解決此緩存問題的標準方法。

您所要的只是將 屬性附加到描述 asp-append-version="true" 檔路徑的標記,如下所示:

<link rel="stylesheet" href="~/css/site.css" asp-append-version="true"/>
<img src="/image/sample.png" asp-append-version="true"/>
<script src="~/js/site.js" asp-append-version="true"></script>

發佈到 Web 後,當您實際存取頁面時,將按如下方式展開它:

<link rel="stylesheet" href="/css/site.css?v=S2ihmzMFFc3FWmBWsR-NiddZWa8kbyaQYBx2FDkIoHs" />
<img src="/image/sample.png?v=Z0tUqQmLt_3L_NSzPmkbZKxL8cMxglf08BwWb5Od5z4" />
<script src="/js/site.js?v=dLGP40S79Xnx6GqUthRF6NWvjvhQ1nOvdVSwaNcgG18"></script>

隨機字串被添加,但每次訪問時都不會更改。 此字串是哈希值,根據引用文件的內容生成。 因此,只要文件的內容保持不變,它們將生成相同的字串。 如果文件的內容發生更改,則更改為新字串。

因此,如果檔相同,則路徑相同,因此快取的檔將優先使用。 如果檔已更新,路徑將發生更改,因此將下載並使用新檔。

順便說一 asp-append-version="true" 下,此屬性通常僅包含放置在 wwwroot 資料夾中的靜態檔。 請注意,隨機字串不會展開,即使設置為其他檔。

關於示例程式

默認專案範本.js site asp-append-version 範本。 site.css 沒有 asp-append-version 附加 。

範例程式 _Layout.cshtml 將 site.js、網站.css asp-append-version 檔添加到每個網站。 我們還添加 img 標記作為參考,並將其添加到 asp-append-version 中。