共用方式為


ASP.NET Core Blazor 靜態檔案

注意

這不是這篇文章的最新版本。 關於目前版本,請參閱 本文的 .NET 10 版本

警告

不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。

本文描述提供靜態檔案的 Blazor 應用程式設定。

在閱讀本文之前,請先參閱 ASP.NET Core 中的靜態檔案,以取得關於使用 Map Static Assets 路由端點慣例來提供靜態檔案的一般資訊。

預先載入的 Blazor 架構靜態資產

在 Blazor Web App中,架構靜態資產會自動使用 Link 標頭預先載入,這可讓瀏覽器在擷取和轉譯初始頁面之前預先載入資源。

在獨立的 Blazor WebAssembly 應用程式中,架構資源會被安排在瀏覽器 index.html 頁面處理的初期進行高優先級的下載和緩存。

  • OverrideHtmlAssetPlaceholders 應用程式項目檔中的 MSBuild 屬性已設定為.csproj

    <PropertyGroup>
      <OverrideHtmlAssetPlaceholders>true</OverrideHtmlAssetPlaceholders>
    </PropertyGroup>
    
  • 下列包含<link>rel="preload"元素存在於<head>wwwroot/index.html內容中:

    <link rel="preload" id="webassembly" />
    

伺服器端 Blazor 應用程式中的靜態資產傳遞

提供靜態資產是由路由端點慣例或下表所述的中間件所管理。

功能 API .NET 版本 描述
映射靜態資產路由端點的慣例 MapStaticAssets .NET 9 或更新版本 優化靜態資產的傳遞至客戶端。
靜態檔案中間件 UseStaticFiles 所有 .NET 版本 提供靜態資產給用戶端,雖未使用"Map Static Assets"的優化,但在某些"Map Static Assets"無法管理的工作中非常有用。

在大部分情況下,地圖靜態資產都可以取代 UseStaticFiles 。 不過,Map Static Assets 已針對在建構與發佈階段從應用程式中的已知位置傳遞資產進行優化。 如果應用程式提供來自其他位置的資產 (例如磁碟或內嵌資源),則應使用 UseStaticFiles

靜態資產映射(MapStaticAssets)也會取代應用程式中呼叫 UseBlazorFrameworkFiles 以提供 Blazor WebAssembly 框架檔案,而且,在 UseBlazorFrameworkFiles 中不需要額外呼叫 Blazor Web App,因為當叫用 AddInteractiveWebAssemblyComponents 時,自動會呼叫 API。

啟用互動式 WebAssembly 或互動式自動轉譯模式時:

  • Blazor 會建立端點以將資源集合公開為 JS 模組。
  • 當 WebAssembly 元件渲染到頁面時,URL 會發送到請求體中,作為已保存的元件狀態。
  • 在 WebAssembly 開機期間,Blazor 會擷取 URL、匯入模組,以及呼叫函式來擷取資產集合,並在記憶體中重新建構它。 URL 專屬於內容並永遠快取,因此只有在更新應用程式之前,每位使用者才需支付一次此額外負荷成本。
  • 資源集合也會在人類可讀取的 URL (_framework/resource-collection.js) 中公開,因此 JS 可以存取資源集合以增強瀏覽,或實作其他架構和協力廠商元件的功能。

靜態檔案中間件 (UseStaticFiles) 適用於下列無法處理 Map Static Assets (MapStaticAssets) 的情況:

  • 從不屬於組建或發布過程中的磁碟中提供檔案,例如,在部署期間或之後新增至應用程式資料夾的檔案。
  • 將路徑前置詞套用至 Blazor WebAssembly 靜態資產檔案,這在「Blazor WebAssembly 資產的前置詞」章節中有詳細說明。
  • 設定檔案副檔名與特定內容類型的對應,以及設定靜態檔案選項,這在「檔案對應和靜態檔案選項」章節中有詳細說明。

如需詳細資訊,請參閱 ASP.NET Core 中的靜態檔案

透過映射靜態資產的路由端點慣例來交付資產

本節適用伺服器端 Blazor 應用程式。

資產會透過 ComponentBase.Assets 屬性傳遞,以解析指定資產的指紋URL。 在下列範例中,Bootstrap、 Blazor 專案範本應用程式樣式表單 (app.css), 和 CSS 隔離樣式表單 (根據應用程式的 命名空間 BlazorSample) 連結在根元件中,通常是 App 元件 (Components/App.razor):

<link rel="stylesheet" href="@Assets["bootstrap/bootstrap.min.css"]" />
<link rel="stylesheet" href="@Assets["app.css"]" />
<link rel="stylesheet" href="@Assets["BlazorSample.styles.css"]" />

ImportMap 元件

本節適用於 Blazor Web App呼叫 MapRazorComponents的 。

元件 ImportMapImportMap)代表一個匯入映射元素(<script type="importmap"></script>),其作用是定義模組腳本的匯入映射。 匯入對應元件會放在根元件的<head>內容中,通常是App元件(Components/App.razor)。

<ImportMap />

如果未將自訂 ImportMapDefinition 指派給匯入對應映射元件,則會根據應用程式的資產產生匯入對應映射。

注意

ImportMapDefinition 實例的建立成本很高,因此建議您在建立其他實例時快取它們。

以下範例演示自訂的匯入對應定義及其所生成的匯入對應。

基本匯入映射

new ImportMapDefinition(
    new Dictionary<string, string>
    {
        { "jquery", "https://cdn.example.com/jquery.js" },
    },
    null,
    null);

上述程式碼會產生下列匯入對應:

{
  "imports": {
    "jquery": "https://cdn.example.com/jquery.js"
  }
}

範疇匯入對應圖表

new ImportMapDefinition(
    null,
    new Dictionary<string, IReadOnlyDictionary<string, string>>
    {
        ["/scoped/"] = new Dictionary<string, string>
        {
            { "jquery", "https://cdn.example.com/jquery.js" },
        }
    },
    null);

上述程式碼會產生下列匯入對應:

{
  "scopes": {
    "/scoped/": {
      "jquery": "https://cdn.example.com/jquery.js"
    }
  }
}

匯入具有完整性驗證的映射:

new ImportMapDefinition(
    new Dictionary<string, string>
    {
        { "jquery", "https://cdn.example.com/jquery.js" },
    },
    null,
    new Dictionary<string, string>
    {
        { "https://cdn.example.com/jquery.js", "sha384-abc123" },
    });

上述程式碼會產生下列匯入對應:

{
  "imports": {
    "jquery": "https://cdn.example.com/jquery.js"
  },
  "integrity": {
    "https://cdn.example.com/jquery.js": "sha384-abc123"
  }
}

合併匯入映射定義 (ImportMapDefinition) 和 ImportMapDefinition.Combine

匯入地圖是從 ResourceAssetCollection 建立的,用來將靜態資產映射到它們唯一的 URL。

ImportMapDefinition.FromResourceCollection(
    new ResourceAssetCollection(
    [
        new ResourceAsset(
            "jquery.fingerprint.js",
            [
                new ResourceAssetProperty("integrity", "sha384-abc123"),
                new ResourceAssetProperty("label", "jquery.js"),
            ])
    ]));

上述程式碼會產生下列匯入對應:

{
  "imports": {
    "./jquery.js": "./jquery.fingerprint.js"
  },
  "integrity": {
    "jquery.fingerprint.js": "sha384-abc123"
  }
}

匯入地圖內容安全策略 (CSP) 違規

本節適用於 Blazor Web App呼叫 MapRazorComponents的 。

元件 ImportMap 被渲染為內嵌 <script> 標記,這違反了嚴格的內容安全策略(CSP),該策略設定了 default-src 指令。

如需範例說明如何透過子資源完整性(SRI)或加密隨機數來解決原則違規問題,請參閱 使用子資源完整性 (SRI) 或隨機數解決 CSP 違規

透過在應用程式的要求處理管線中呼叫 UseStaticFiles,設定靜態檔案中介軟體以提供靜態資產給用戶端。 如需詳細資訊,請參閱 ASP.NET Core 中的靜態檔案

在 .NET 8 之前的版本中,會透過靜態檔案中介軟體提供 Blazor 指令碼這類 Blazor 架構靜態檔案。 在 .NET 8 或更新版本中,會使用端點路由來對應 Blazor 架構靜態檔案,而且不再使用靜態檔案中介軟體。

將客戶端的靜態資產指紋化於獨立的Blazor WebAssembly應用程式中

在建置/發佈期間的獨立 Blazor WebAssembly 應用程式中,架構會在 index.html 中以建置期間計算出的值覆寫佔位元,以指紋化靜態資產並用於客戶端呈現。 指紋會放入blazor.webassembly.js腳本檔名中,並生成其他 .NET 資產的導入映射。

獨立wwwwoot/index.html應用程式的Blazor WebAssembly檔案中必須有以下設定,才能使用指紋功能:

<head>
    ...
    <script type="importmap"></script>
    ...
</head>

<body>
    ...
    <script src="_framework/blazor.webassembly#[.{fingerprint}].js"></script>
    ...
</body>

</html>

在項目檔 (.csproj) 中 <OverrideHtmlAssetPlaceholders> ,屬性會設定為 true

<PropertyGroup>
  <OverrideHtmlAssetPlaceholders>true</OverrideHtmlAssetPlaceholders>
</PropertyGroup>

解析 JavaScript Interop 的匯入時,瀏覽器會透過匯入對應以解析具有指紋的檔案。

任何在index.html中具有指紋標記的腳本都會由框架進行指紋識別。 例如,在應用程式的scripts.js資料夾中名為wwwroot/js的腳本檔案,會在副檔名前加上#[.{fingerprint}] 以進行指紋處理(.js):

<script src="js/scripts#[.{fingerprint}].js"></script>

在Blazor Web App中對客戶端靜態資產進行指紋化

針對Blazor Web App用戶端轉譯(CSR)(Interactive Auto 或 Interactive WebAssembly 轉譯模式),透過採用,啟用了靜態資產伺服器端MapStaticAssetsImportMap屬性。 如需詳細資訊,請參閱 ASP.NET Core 中的靜態檔案

若要為其他適用於 CSR 的 JavaScript 模組產生指紋,請使用應用程式項目檔案(<StaticWebAssetFingerprintPattern> 中的項目 .csproj)。 在下列範例中,會針對應用程式中所有開發人員提供的 .mjs 檔案新增指紋:

<ItemGroup>
  <StaticWebAssetFingerprintPattern Include="JSModule" Pattern="*.mjs" 
    Expression="#[.{fingerprint}]!" />
</ItemGroup>

解析 JavaScript Interop 的匯入時,瀏覽器會透過匯入對應以解析具有指紋的檔案。

本章節適用於所有 .NET 版本和 Blazor 應用程式。

下表會摘要說明 .NET 版本的靜態檔案 <link>href 格式。

如需放置靜態檔案連結的 <head> 內容的位置,請參閱 ASP.NET Core Blazor 專案結構。 靜態資產連結也可以使用個別 <HeadContent> 元件中的 來提供。

如需放置靜態檔案連結的 <head> 內容的位置,請參閱 ASP.NET Core Blazor 專案結構

.NET 9 或更新版本

應用程式類型 href 範例
Blazor Web App @Assets["{PATH}"] <link rel="stylesheet" href="@Assets["app.css"]" />
<link href="@Assets["_content/ComponentLib/styles.css"]" rel="stylesheet" />
Blazor Server† @Assets["{PATH}"] <link href="@Assets["css/site.css"]" rel="stylesheet" />
<link href="@Assets["_content/ComponentLib/styles.css"]" rel="stylesheet" />
獨立 Blazor WebAssembly {PATH} <link rel="stylesheet" href="css/app.css" />
<link href="_content/ComponentLib/styles.css" rel="stylesheet" />

.NET 8.x

應用程式類型 href 範例
Blazor Web App {PATH} <link rel="stylesheet" href="app.css" />
<link href="_content/ComponentLib/styles.css" rel="stylesheet" />
Blazor Server† {PATH} <link href="css/site.css" rel="stylesheet" />
<link href="_content/ComponentLib/styles.css" rel="stylesheet" />
獨立 Blazor WebAssembly {PATH} <link rel="stylesheet" href="css/app.css" />
<link href="_content/ComponentLib/styles.css" rel="stylesheet" />

.NET 7.x 或更早版本

應用程式類型 href 範例
Blazor Server† {PATH} <link href="css/site.css" rel="stylesheet" />
<link href="_content/ComponentLib/styles.css" rel="stylesheet" />
主辦的 Blazor WebAssembly‡ {PATH} <link href="css/app.css" rel="stylesheet" />
<link href="_content/ComponentLib/styles.css" rel="stylesheet" />
Blazor WebAssembly {PATH} <link href="css/app.css" rel="stylesheet" />
<link href="_content/ComponentLib/styles.css" rel="stylesheet" />

.NET 8 或更新版本支援 †Blazor Server,但其在 .NET 7 之後不再是專案範本。
‡建議您在採用 .NET 8 或更新版本時,將託管的 Blazor WebAssembly 應用程式更新為 Blazor Web App。

靜態 Web 資產專案模式

本章節適用於 .Client的 Blazor Web App 專案。

<StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode>.Client 專案中所需的 Blazor Web App 設定會將 Blazor WebAssembly 靜態資產表現方式還原回預設值,讓專案作為託管專案的一部分運作。 Blazor WebAssembly SDK (Microsoft.NET.Sdk.BlazorWebAssembly) 會以特定方式設定靜態 Web 資產,以「獨立」模式運作,而伺服器只需取用程式庫的輸出即可。 這不適用於 Blazor Web App,其中應用程式的 WebAssembly 部分是主機的邏輯部分,而且必須表現出更像程式庫的行為。 例如,專案不會公開樣式組合 (例如 BlazorSample.Client.styles.css),而是只向主機提供專案組合,讓主機可以將該組合包含在自己的樣式組合中。

不支援變更 Default 的值 (<StaticWebAssetProjectMode>) 或從 .Client 專案移除屬性。

Blazor WebAssembly 資產的字首

本章節適用於 Blazor Web App項。

使用 WebAssemblyComponentsEndpointOptions.PathPrefix 端點選項來設定用於指示 Blazor WebAssembly 資產的前綴的路徑字串。 路徑必須對應至參考的 Blazor WebAssembly 應用程式專案。

endpoints.MapRazorComponents<App>()
    .AddInteractiveWebAssemblyRenderMode(options => 
        options.PathPrefix = "{PATH PREFIX}");

在上述範例中,{PATH PREFIX} 預留位置是路徑前置詞,且開頭必須是正斜線 (/)。

在下列範例中,路徑前置詞會設定為 /path-prefix

endpoints.MapRazorComponents<App>()
    .AddInteractiveWebAssemblyRenderMode(options => 
        options.PathPrefix = "/path-prefix");

靜態 Web 資產基礎路徑

本節適用獨立 Blazor WebAssembly 應用程式。

發佈應用程式會將應用程式的靜態資產,包括 Blazor 架構檔案(_framework 資料夾資產),放在已發佈輸出中的根路徑 (/)。 專案檔 (<StaticWebAssetBasePath>) 中指定的 .csproj 屬性會將基礎路徑設定為非根路徑:

<PropertyGroup>
  <StaticWebAssetBasePath>{PATH}</StaticWebAssetBasePath>
</PropertyGroup>

在上述範例中,{PATH} 預留位置是路徑。

若未設定 <StaticWebAssetBasePath> 屬性,獨立應用程式會在 /BlazorStandaloneSample/bin/Release/{TFM}/publish/wwwroot/ 發佈。

在上述範例中 {TFM} ,佔位符是 Target Framework Moniker (TFM)

如果獨立 <StaticWebAssetBasePath> 應用程式中的 Blazor WebAssembly 屬性將已發佈的靜態資產路徑設定為 app1,則已發佈輸出中應用程式的根路徑為 /app1

在獨立 Blazor WebAssembly 應用程式的專案檔中 (.csproj):

<PropertyGroup>
  <StaticWebAssetBasePath>app1</StaticWebAssetBasePath>
</PropertyGroup>

在已發佈的輸出中,獨立運行的 Blazor WebAssembly 應用程式的路徑是 /BlazorStandaloneSample/bin/Release/{TFM}/publish/wwwroot/app1/

在上述範例中 {TFM} ,佔位符是 Target Framework Moniker (TFM)

本節適用獨立 Blazor WebAssembly 應用程式和裝載的 Blazor WebAssembly 方案。

發佈應用程式會將應用程式的靜態資產,包括 Blazor 架構檔案(_framework 資料夾資產),放在已發佈輸出中的根路徑 (/)。 專案檔 (<StaticWebAssetBasePath>) 中指定的 .csproj 屬性會將基礎路徑設定為非根路徑:

<PropertyGroup>
  <StaticWebAssetBasePath>{PATH}</StaticWebAssetBasePath>
</PropertyGroup>

在上述範例中,{PATH} 預留位置是路徑。

若未設定 <StaticWebAssetBasePath> 屬性,裝載的方案或獨立應用程式的用戶端應用程式會在下列路徑發佈:

  • 託管的 Server 解決方案中的 Blazor WebAssembly 專案:/BlazorHostedSample/Server/bin/Release/{TFM}/publish/wwwroot/
  • 在獨立 Blazor WebAssembly 應用程式中:/BlazorStandaloneSample/bin/Release/{TFM}/publish/wwwroot/

如果裝載的 <StaticWebAssetBasePath> 應用程式或獨立 Client 應用程式中 Blazor WebAssembly 專案的 Blazor WebAssembly 屬性將已發佈的靜態資產路徑設定為 app1,則已發佈輸出中應用程式的根路徑為 /app1

Client 應用程式的專案檔 (.csproj) 或獨立 Blazor WebAssembly 應用程式的專案檔中 (.csproj):

<PropertyGroup>
  <StaticWebAssetBasePath>app1</StaticWebAssetBasePath>
</PropertyGroup>

在已發佈的產出中:

  • 在託管 Server 解決方案的 Blazor WebAssembly 專案中,客戶端應用程式的路徑為:/BlazorHostedSample/Server/bin/Release/{TFM}/publish/wwwroot/app1/
  • 獨立 Blazor WebAssembly 應用程式的路徑:/BlazorStandaloneSample/bin/Release/{TFM}/publish/wwwroot/app1/

<StaticWebAssetBasePath> 屬性最常用來控制單一裝載部署中多個 Blazor WebAssembly 應用程式已發佈的靜態資產的路徑。 如需詳細資訊,請參閱多個裝載的 ASP.NET Core Blazor WebAssembly 應用程式。 屬性在獨立 Blazor WebAssembly 應用程式中也有效。

在上述範例中 {TFM} ,佔位符是 Target Framework Moniker (TFM)

文件對映和靜態文件選項

本節適用於伺服器端靜態檔案。

若要使用 FileExtensionContentTypeProvider 或設定其他 StaticFileOptions 來建立其他檔案對應,請使用下列其中一種方法。 在下列範例中,{EXTENSION} 預留位置是副檔名,而 {CONTENT TYPE} 預留位置是內容類型。

  • 檔案中,使用 Program 透過 StaticFileOptions 設定選項:

    using Microsoft.AspNetCore.StaticFiles;
    
    ...
    
    var provider = new FileExtensionContentTypeProvider();
    provider.Mappings["{EXTENSION}"] = "{CONTENT TYPE}";
    
    builder.Services.Configure<StaticFileOptions>(options =>
    {
        options.ContentTypeProvider = provider;
    });
    

    此方法會設定用來提供 Blazor 指令碼的相同檔案提供者。 請確定您的自訂設定不會干擾提供 Blazor 指令碼。 例如,請勿使用 provider.Mappings.Remove(".js") 設定提供者來移除 JavaScript 檔案的映射。

  • UseStaticFiles 檔案中使用對 Program 的兩個呼叫:

    • 使用 StaticFileOptions 在第一次呼叫中設定自訂檔案提供者。
    • 第二個中介軟體會提供 Blazor 指令碼,其會使用 Blazor 架構提供的預設靜態檔案設定。
    using Microsoft.AspNetCore.StaticFiles;
    
    ...
    
    var provider = new FileExtensionContentTypeProvider();
    provider.Mappings["{EXTENSION}"] = "{CONTENT TYPE}";
    
    app.UseStaticFiles(new StaticFileOptions { ContentTypeProvider = provider });
    app.UseStaticFiles();
    
  • 您可以透過使用 _framework/blazor.server.js 來執行自訂的靜態檔案中介軟體,以避免影響 MapWhen 的服務:

    app.MapWhen(ctx => !ctx.Request.Path
        .StartsWithSegments("/_framework/blazor.server.js"),
            subApp => subApp.UseStaticFiles(new StaticFileOptions() { ... }));
    

從多個位置提供檔案

本章節的指導僅適用於 Blazor Web App。

若要使用 CompositeFileProvider 提供來自多個位置的檔案:

範例:

在名為 AdditionalStaticAssets 的伺服器專案中建立新資料夾。 將影像放入資料夾中。

將下列 using 陳述式新增至伺服器專案的 Program 檔案頂端:

using Microsoft.Extensions.FileProviders;

在伺服器專案的Program檔案中,在呼叫之前,新增下列程式碼:

var secondaryProvider = new PhysicalFileProvider(
    Path.Combine(builder.Environment.ContentRootPath, "AdditionalStaticAssets"));
app.Environment.WebRootFileProvider = new CompositeFileProvider(
    app.Environment.WebRootFileProvider, secondaryProvider);

在應用程式的 Home 元件 (Home.razor) 標記中,參考具有 <img> 標籤的影像:

<img src="{IMAGE FILE NAME}" alt="{ALT TEXT}" />

在前述範例中:

  • {IMAGE FILE NAME} 預留位置是圖像檔案名稱。 如果影像檔位於 AdditionalStaticAssets 資料夾的根目錄,則不需要提供路徑區段。
  • {ALT TEXT} 佔位符是影像替代文字。

執行應用程式。

其他資源