ASP.NET Core Blazor WebAssembly .NET 執行時間和應用程式套件組合快取

注意

這不是這篇文章的最新版本。 如需目前版本,請參閱本文的 .NET 8 版本

重要

這些發行前產品的相關資訊在產品正式發行前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。

如需目前版本,請參閱本文的 .NET 8 版本

當 Blazor WebAssembly 應用程式在瀏覽器中載入時,該應用程式會從伺服器下載啟動資源:

  • 要啟動載入應用程式的 JavaScript 程式碼
  • .NET 執行階段和組件
  • 地區設定特定資料

除了 Blazor 的啟動資源檔案 (blazor.boot.json) 之外,WebAssembly .NET 執行階段和應用程式套件組合檔案都會在用戶端上快取。 blazor.boot.json 檔案包含組成必須下載的應用程式的檔案資訊清單,以及用於偵測是否有任何啟動資源已變更的檔案內容的雜湊值。 Blazor 會使用瀏覽器 Cache API 來快取下載的檔案。

Blazor WebAssembly 在下載應用程式的啟動檔案時,會指示瀏覽器對回應執行完整性檢查。 Blazor 會傳送 DLL (.dll)、WebAssembly (.wasm) 和 blazor.boot.json 檔案中其他檔案的 SHA-256 雜湊值。 所快取檔案的檔案雜湊會與 blazor.boot.json 檔案中的雜湊進行比較。 對於具有相符雜湊的快取檔案,Blazor 會使用快取的檔案。 否則,系統會向伺服器要求檔案。 檔案下載完成後,系統會再次檢查其雜湊以驗證完整性。 如果任何所下載檔案的完整性檢查失敗,瀏覽器就會產生錯誤。

Blazor 用於管理檔案完整性的演算法:

  • 確保應用程式不會有載入一組不一致檔案的風險,例如,在使用者正在下載應用程式檔時,將新的部署套用至您的網頁伺服器的話。 檔案不一致可能會導致應用程式故障。
  • 確保使用者的瀏覽器永遠不會快取不一致或無效的回應,即使使用者手動重新整理頁面,這也可能會導致應用程式無法啟動。
  • 在預期的 SHA-256 雜湊本身變更之前,讓其可以安全地快取回應,且不會檢查伺服器端變更,以便後續的頁面載入涉及較少的要求,並更快地完成。

如果網頁伺服器傳回不符合預期 SHA-256 雜湊的回應,則瀏覽器開發人員主控台中會出現類似下列範例的錯誤:

針對具有已計算 SHA-256 完整性 'IIa70iwvmEg5WiDV17OpQ5eCztNYqL186J56852RpJY=' 的資源 'https://myapp.example.com/_framework/MyBlazorApp.dll',在其 'integrity' 屬性中找不到有效的摘要。 該資源已遭到封鎖。

在大部分情況下,該警告並非代表完整性檢查有問題。 相反地,該警告通常表示存在一些其他問題。

注意

.NET 參考來源的文件連結通常會載入存放庫的預設分支,這表示下一版 .NET 的目前開發。 若要選取特定版本的標籤,請使用 [切換分支或標籤] 下拉式清單。 如需詳細資訊,請參閱如何選取 ASP.NET Core 原始程式碼 (dotnet/AspNetCore.Docs #26205) 的版本標籤

診斷完整性問題

在建置應用程式時,產生的 blazor.boot.json 資訊清單會描述產生建置輸出時開機資源的 SHA-256 雜湊。 只要 blazor.boot.json 中的 SHA-256 雜湊符合傳遞至瀏覽器的檔案,完整性檢查就會通過。

檢查失敗的常見原因包括:

  • 網頁伺服器的回應是一個錯誤 (例如,404 - 找不到500 - 內部伺服器錯誤),而不是瀏覽器所要求的檔案。 瀏覽器會將這回報為完整性檢查失敗,而不是回應失敗。
  • 某些項目導致檔案內容在檔案建置時和檔案傳遞至瀏覽器時發生了變更。 可能導致此情況的原因為:
    • 如果您或建置工具手動修改建置輸出。
    • 如果部署程序的某些方面修改了檔案。 例如,如果您使用 Git 型部署機制,請記住,如果您認可 Windows 上的檔案,並在 Linux 上將檔案簽出,Git 會以透明的方式將 Windows 樣式的行尾轉換成 Unix 樣式的行尾。 變更檔案行尾就會變更 SHA-256 雜湊。 若要避免此問題,請考慮使用 .gitattributes 將組建成品視為 binary 檔案
    • 網頁伺服器會在提供檔案內容時修改檔案內容。 例如,某些內容散發網路 (CDN) 會自動嘗試縮製 HTML,藉此修改 HTML。 您可能需要停用這類功能。
  • blazor.boot.json 檔案無法正確載入或在用戶端上以不正確的方式加以快取。 常見原因包括下列任一項:
    • 設定錯誤或故障的自訂開發人員程式碼。
    • 一或多個設定錯誤的中繼快取層。

若要診斷您的案例適用上述哪一項:

  1. 讀取錯誤訊息以記下是哪一個檔案觸發錯誤。
  2. 開啟瀏覽器的開發人員工具,並查看 [網路] 索引標籤。如有必要,請重新載入頁面以查看要求和回應的清單。 在該清單中尋找觸發錯誤的檔案。
  3. 檢查回應中的 HTTP 狀態碼。 如果伺服器傳回 200 - 正常以外的任何錯誤 (或其他 2xx 狀態碼),則表示您有伺服器端問題需要診斷。 例如,狀態碼 403 表示發生授權問題,而狀態碼 500 表示伺服器以未指定的方式失敗。 請參閱伺服器端記錄以診斷和修正應用程式。
  4. 如果資源的狀態碼為 200 - 正常,請查看瀏覽器開發人員工具中的回應內容,並檢查內容是否符合預期的資料。 例如,常見的問題是路由設定錯誤,使得即使是其他檔案的要求也傳回您的 index.html 資料。 請確定 .wasm 要求的回應是 WebAssembly 二進位檔,而 .dll 要求的回應是 .NET 組件二進位檔。 如果不是,則表示您有伺服器端的路由問題需要診斷。
  5. 使用針對完整性 PowerShell 指令碼進行疑難排解來設法驗證應用程式的已發行和已部署輸出。

如果您確認伺服器傳回看似合理的正確資料,則表示檔案的建置和傳遞之間必定有其他某些項目修改了內容。 若要調查此情況:

  • 檢查建置工具鏈和部署機制,以免其在檔案建置完成後修改檔案。 此情況的其中一個範例是當 Git 轉換檔案行尾時,如先前所述。
  • 檢查網頁伺服器或 CDN 組態,以免其設定為動態修改回應 (例如,嘗試縮製 HTML)。 網頁伺服器可以實作 HTTP 壓縮 (例如,傳回 content-encoding: brcontent-encoding: gzip),因為這不會影響解壓縮後的結果。 不過,網頁伺服器不能修改未壓縮的資料。

針對完整性 PowerShell 指令碼進行疑難排解

使用 integrity.ps1 PowerShell 指令碼來驗證已發行和已部署的 Blazor 應用程式。 這個指令碼會提供給 PowerShell Core 7 或更新版本,以作為應用程式有 Blazor 架構所無法識別的完整性問題時的解決起點。 這個指令碼可能需要針對您的應用程式加以自訂,如果在 7.2.0 版之後的 PowerShell 版本上執行的話也是如此。

這個指令碼會檢查 publish 資料夾中的檔案,並從已部署的應用程式下載,以偵測包含完整性雜湊的不同資訊清單中的問題。 這些檢查應該能偵測出最常見的問題:

  • 您修改了已發行輸出中的檔案,卻沒注意到。
  • 應用程式未以正確方式部署至部署目標,或部署目標的環境內發生了某些變更。
  • 已部署的應用程式與發行應用程式時所產生的輸出之間有差異。

在 PowerShell 命令殼層中使用下列命令叫用指令碼:

.\integrity.ps1 {BASE URL} {PUBLISH OUTPUT FOLDER}

在下列範例中,指令碼會在 https://localhost:5001/ 於本機執行的應用程式上執行:

.\integrity.ps1 https://localhost:5001/ C:\TestApps\BlazorSample\bin\Release\net6.0\publish\

預留位置:

  • {BASE URL}:已部署應用程式的 URL。 必須有尾端斜線 (/)。
  • {PUBLISH OUTPUT FOLDER}:應用程式的 publish 資料夾或發行應用程式以進行部署之所在位置的路徑。

注意

在複製 dotnet/AspNetCore.Docs GitHub 存放庫時,integrity.ps1 指令碼可能會遭到 Bitdefender 或系統上存在的其他病毒掃描程式隔離。 該檔案通常會被病毒掃描程式的啟發式掃描技術所截獲,因為該技術只會尋找檔案中可能表示有惡意程式碼存在的模式。 若要防止病毒掃描程式隔離檔案,請在複製存放庫之前,於病毒掃描程式中新增例外狀況。 下列範例是該指令碼在 Windows 系統上的典型路徑。 若為其他系統,請視需要調整路徑。 預留位置 {USER} 是使用者的路徑線段。

C:\Users\{USER}\Documents\GitHub\AspNetCore.Docs\aspnetcore\blazor\host-and-deploy\webassembly\_samples\integrity.ps1

警告建立病毒掃描程式例外狀況是危險行為,請只在您確定檔案安全無虞時才這麼做。

比較檔案總和檢查碼的值與有效總和檢查碼的值並無法保證檔案安全無虞,但對惡意使用者來說,以維護總和檢查碼值的方式修改檔案並不是件簡單的事。 因此,將總和檢查碼作為一般的安全性方法會有用。 比較本機 integrity.ps1 檔案的總和檢查碼與下列其中一個值:

  • SHA256:32c24cb667d79a701135cb72f6bae490d81703323f61b8af2c7e5e5dc0f0c2bb
  • MD5:9cee7d7ec86ee809a329b5406fbf21a8

使用下列命令取得檔案在 Windows OS 上的總和檢查碼。 針對 {PATH AND FILE NAME} 預留位置提供路徑和檔案名稱,並指出要為 {SHA512|MD5} 預留位置產生的總和檢查碼類型 (SHA256MD5):

CertUtil -hashfile {PATH AND FILE NAME} {SHA256|MD5}

如果您有任何理由擔心環境中的總和檢查碼驗證不夠安全,請向組織的安全性主管請教以尋求指導。

如需詳細資訊,請參閱 Microsoft Defender 防病毒軟體的威脅防護概觀 (英文)。

停用非 PWA 應用程式的資源快取和完整性檢查

在大部分情況下,請勿停用完整性檢查。 停用完整性檢查並無法解決造成非預期回應的基礎問題,而且會導致您失去先前列出的好處。

在某些情況下,您無法信賴網頁伺服器會傳回一致的回應,此時您別無選擇,只能暫時停用完整性檢查,直到解決基礎問題為止。

若要停用完整性檢查,請將下列內容新增至 Blazor WebAssembly 應用程式專案檔 (.csproj) 中的屬性群組:

<BlazorCacheBootResources>false</BlazorCacheBootResources>

BlazorCacheBootResources 也會根據檔案的 SHA-256 雜湊來停用 Blazor 預設的快取 .dll.wasm 和其他檔案的行為,因為該屬性指出 SHA-256 雜湊的正確性不值得信賴。 即使使用此設定,瀏覽器的一般 HTTP 快取仍可能會快取這些檔案,但是否會發生此情況取決於網頁伺服器的組態及其提供的 cache-control 標頭。

注意

BlazorCacheBootResources 屬性不會停用漸進式 Web 應用程式 (PWA) 的完整性檢查。 如需有關 PWA 的指導,請參閱停用 PWA 的完整性檢查一節。

我們無法完整提供需要停用完整性檢查的案例清單。 伺服器能以超出 Blazor 架構範圍的任意方式回應要求。 此架構會提供 BlazorCacheBootResources 設定來讓應用程式能夠執行,但代價是會失去應用程式可以提供的完整性保證。 再次重申,不建議您停用完整性檢查,尤其是在生產部署上。 開發人員應設法解決導致完整性檢查失敗的基礎完整性問題才對。

一些可能導致完整性問題的一般案例如下:

  • 在無法檢查完整性的 HTTP 上執行。
  • 如果您的部署程序以任何方式修改發行後的檔案。
  • 如果您的主機以任何方式修改檔案。

停用 PWA 的資源快取和完整性檢查

Blazor 的漸進式 Web 應用程式 (PWA) 範本包含建議的 service-worker.published.js 檔案,此檔案負責擷取和儲存應用程式檔案以供離線使用。 這是與一般應用程式啟動機制不同的程序,並有自己的個別完整性檢查邏輯。

service-worker.published.js 檔案內有下面這行:

.map(asset => new Request(asset.url, { integrity: asset.hash }));

若要停用完整性檢查,請將這行變更為下列內容,以移除 integrity 參數:

.map(asset => new Request(asset.url));

再次重申,停用完整性檢查表示您會失去完整性檢查所提供的安全性保證。 例如,如果使用者的瀏覽器在您部署新版本時恰好快取應用程式,則會有其可能從舊部署快取一些檔案,並從新部署快取一些檔案的風險。 如果發生這種情況,應用程式會卡在中斷狀態,直到您部署進一步的更新為止。

其他資源

啟動資源載入