ASP.NET Core Blazor 靜態檔案
注意
這不是這篇文章的最新版本。 如需目前的版本,請參閱 本文的 .NET 9 版本。
警告
不再支援此版本的 ASP.NET Core。 如需詳細資訊,請參閱 .NET 和 .NET Core 支持原則。 如需目前的版本,請參閱 本文的 .NET 9 版本。
本文描述提供靜態檔案的 Blazor 應用程式設定。
伺服器端 Blazor 應用程式中的靜態資產傳遞
提供靜態資產是由路由端點慣例或下表所述的中間件所管理。
功能 | API | .NET 版本 | 描述 |
---|---|---|---|
對應靜態資產路由端點慣例 | MapStaticAssets | .NET 9 或更新版本 | 最佳化向用戶端傳遞靜態資產。 |
靜態檔案中間件 | UseStaticFiles | 所有 .NET 版本 | 提供靜態資產給用戶端,而不優化地圖靜態資產,但對於對應靜態資產無法管理的某些工作很有用。 |
在應用程式的要求處理管線中呼叫 MapStaticAssets ,以設定對應靜態資產,其會執行下列動作:
- 設定 ETag 和 Last-Modified 標頭。
- 設定快取標頭。
- 使用快取中介軟體。
- 可能的話,請提供壓縮的靜態資產。
- 與內容傳遞網路 (CDN) (例如,Azure CDN),以更接近使用者的方式提供應用程式的靜態資產。
- 指紋資產用於防止重複使用舊版的檔案。
對應靜態資產的運作方式是結合組建和發佈程式,以收集應用程式中靜態資產的相關信息。 執行階段程式庫會利用此資訊來有效地向瀏覽器提供靜態資產。
在大部分情況下,地圖靜態資產都可以取代 UseStaticFiles 。 不過,Map Static Assets 已針對在建置和發佈時間從應用程式中的已知位置提供資產優化。 如果應用程式提供來自其他位置的資產 (例如磁碟或內嵌資源),則應使用 UseStaticFiles。
對應靜態資產 (MapStaticAssets) 會取代服務Blazor WebAssembly架構檔案之應用程式中的呼叫UseBlazorFrameworkFiles,而且不需要在 中Blazor Web App明確呼叫UseBlazorFrameworkFiles,因為叫用 時AddInteractiveWebAssemblyComponents會自動呼叫 API。
對應靜態資產提供下列在呼叫 UseStaticFiles時無法使用的優點:
- 應用程式中所有資產的建置時間壓縮,包括 JavaScript (JS) 和樣式表,但不包括已壓縮的影像和字型資產。 Gzip (
Content-Encoding: gz
) 壓縮會用於開發期間。 發佈期間會將 Gzip 和 Brotli (Content-Encoding: br
) 壓縮搭配使用。 - 在建置時間使用每個檔案內容的 SHA-256 雜湊的 Base64 編碼字串對所有資產進行指紋辨識。 這可防止重複使用舊版本的檔案,即使已快取舊檔案也一樣。 對於已經過指紋辨識的資產,會使用
immutable
指示詞進行快取,這會導致瀏覽器在變更之前絕不會再次要求資產。 對於不支援immutable
指示詞的瀏覽器,會新增max-age
指示詞。 - 在 Visual Studio 熱重新載入開發測試期間:
- 完整性資訊會從資產中移除,以避免在應用程式執行時因檔案變更而發生問題。
- 不會快取靜態資產,因此無法確保瀏覽器一律擷取目前的內容。
啟用互動式 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"]" />
匯入對應
本節適用伺服器端 Blazor 應用程式。
匯入對應元件 (ImportMap) 代表匯入對應專案 (<script type="importmap"></script>
) ,定義模組腳本的匯入對應。 匯入對應元件會放在根元件的內容中 <head>
,通常是 App
元件 (Components/App.razor
)。
<ImportMap />
如果未將自定義 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"
}
}
透過在應用程式的要求處理管線中呼叫 UseStaticFiles,設定靜態檔案中介軟體以提供靜態資產給用戶端。 如需詳細資訊,請參閱 ASP.NET Core 中的靜態檔案。
在 .NET 8 之前的版本中,會透過靜態檔案中介軟體提供 Blazor 指令碼這類 Blazor 架構靜態檔案。 在 .NET 8 或更新版本中,會使用端點路由來對應 Blazor 架構靜態檔案,而且不再使用靜態檔案中介軟體。
靜態檔案 <link>
href
格式的摘要
本章節適用於所有 .NET 版本和 Blazor 應用程式。
下表會摘要說明 .NET 版本的靜態檔案 <link>
href
格式。
如需放置靜態檔案連結的 <head>
內容的位置,請參閱 ASP.NET Core Blazor 專案結構。 靜態資產連結也可以使用個別 Razor 元件中的 <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 資產專案模式
本章節適用於 Blazor Web App的 .Client
專案。
Blazor Web App 的 .Client
專案中所需的 <StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode>
設定會將 Blazor WebAssembly 靜態資產表現方式還原回預設值,讓專案作為託管專案的一部分運作。 Blazor WebAssembly SDK (Microsoft.NET.Sdk.BlazorWebAssembly
) 會以特定方式設定靜態 Web 資產,以「獨立」模式運作,而伺服器只需取用程式庫的輸出即可。 這不適用於 Blazor Web App,其中應用程式的 WebAssembly 部分是主機的邏輯部分,而且必須表現出更像程式庫的行為。 例如,專案不會公開樣式組合 (例如 BlazorSample.Client.styles.css
),而是只向主機提供專案組合,讓主機可以將該組合包含在自己的樣式組合中。
不支援變更 <StaticWebAssetProjectMode>
的值 (Default
) 或從 .Client
專案移除屬性。
非 Development
環境中的靜態檔案
本節適用於伺服器端靜態檔案。
在本機執行應用程式時,靜態 Web 資產只會在 Development 環境中啟用。 若要在本機開發和測試期間為 Development 以外的環境啟用靜態檔案 (例如,Staging),請在 Program
檔案中的 WebApplicationBuilder 上呼叫 UseStaticWebAssets。
警告
呼叫 UseStaticWebAssets 以取得防止在生產環境中啟用功能的確切環境,因為在生產環境中呼叫時,它會從磁碟上專案以外的不同位置提供檔案。 本節中的範例會呼叫 IsStaging 來檢查 Staging 環境。
if (builder.Environment.IsStaging())
{
builder.WebHost.UseStaticWebAssets();
}
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
資料夾資產),放在已發佈輸出中的根路徑 (/
)。 專案檔 (.csproj
) 中指定的 <StaticWebAssetBasePath>
屬性會將基礎路徑設定為非根路徑:
<PropertyGroup>
<StaticWebAssetBasePath>{PATH}</StaticWebAssetBasePath>
</PropertyGroup>
在上述範例中,{PATH}
預留位置是路徑。
若未設定 <StaticWebAssetBasePath>
屬性,獨立應用程式會在 /BlazorStandaloneSample/bin/Release/{TFM}/publish/wwwroot/
發佈。
在上述範例中,{TFM}
預留位置是目標 Framework Moniker (TFM) (例如,net6.0
)。
如果獨立 Blazor WebAssembly 應用程式中的 <StaticWebAssetBasePath>
屬性將已發佈的靜態資產路徑設定為 app1
,則已發佈輸出中應用程式的根路徑為 /app1
。
在獨立 Blazor WebAssembly 應用程式的專案檔中 (.csproj
):
<PropertyGroup>
<StaticWebAssetBasePath>app1</StaticWebAssetBasePath>
</PropertyGroup>
在發佈的輸出中,獨立 Blazor WebAssembly 應用程式的路徑為 /BlazorStandaloneSample/bin/Release/{TFM}/publish/wwwroot/app1/
。
在上述範例中,{TFM}
預留位置是目標 Framework Moniker (TFM) (例如,net6.0
)。
本節適用獨立 Blazor WebAssembly 應用程式和裝載的 Blazor WebAssembly 方案。
發佈應用程式會將應用程式的靜態資產,包括 Blazor 架構檔案(_framework
資料夾資產),放在已發佈輸出中的根路徑 (/
)。 專案檔 (.csproj
) 中指定的 <StaticWebAssetBasePath>
屬性會將基礎路徑設定為非根路徑:
<PropertyGroup>
<StaticWebAssetBasePath>{PATH}</StaticWebAssetBasePath>
</PropertyGroup>
在上述範例中,{PATH}
預留位置是路徑。
若未設定 <StaticWebAssetBasePath>
屬性,裝載的方案或獨立應用程式的用戶端應用程式會在下列路徑發佈:
- 裝載的 Blazor WebAssembly 方案的 Server 專案:
/BlazorHostedSample/Server/bin/Release/{TFM}/publish/wwwroot/
- 在獨立 Blazor WebAssembly 應用程式中:
/BlazorStandaloneSample/bin/Release/{TFM}/publish/wwwroot/
如果裝載的 Blazor WebAssembly 應用程式或獨立 Blazor WebAssembly 應用程式中 Client 專案的 <StaticWebAssetBasePath>
屬性將已發佈的靜態資產路徑設定為 app1
,則已發佈輸出中應用程式的根路徑為 /app1
。
在 Client 應用程式的專案檔 (.csproj
) 或獨立 Blazor WebAssembly 應用程式的專案檔中 (.csproj
):
<PropertyGroup>
<StaticWebAssetBasePath>app1</StaticWebAssetBasePath>
</PropertyGroup>
在發佈的輸出中:
- 裝載的 Blazor WebAssembly 方案的 Server 專案中用戶端應用程式的路徑:
/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}
預留位置是目標 Framework Moniker (TFM) (例如,net6.0
)。
檔案對應和靜態檔案選項
本節適用於伺服器端靜態檔案。
若要使用 FileExtensionContentTypeProvider 或設定其他 StaticFileOptions 來建立其他檔案對應,請使用下列其中一種方法。 在下列範例中,{EXTENSION}
預留位置是副檔名,而 {CONTENT TYPE}
預留位置是內容類型。 下列 API 的命名空間為 Microsoft.AspNetCore.StaticFiles。
使用 StaticFileOptions 在
Program
檔案中透過相依性插入 (DI) 設定選項:var provider = new FileExtensionContentTypeProvider(); provider.Mappings["{EXTENSION}"] = "{CONTENT TYPE}"; builder.Services.Configure<StaticFileOptions>(options => { options.ContentTypeProvider = provider; }); app.UseStaticFiles();
將 StaticFileOptions 直接傳遞至
Program
檔案中的 UseStaticFiles:var provider = new FileExtensionContentTypeProvider(); provider.Mappings["{EXTENSION}"] = "{CONTENT TYPE}"; app.UseStaticFiles(new StaticFileOptions { ContentTypeProvider = provider });
若要使用 FileExtensionContentTypeProvider 或設定其他 StaticFileOptions 來建立其他檔案對應,請使用下列其中一種方法。 在下列範例中,{EXTENSION}
預留位置是副檔名,而 {CONTENT TYPE}
預留位置是內容類型。
使用 StaticFileOptions 在
Program
檔案中透過相依性插入 (DI) 設定選項: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 檔案的對應。在
Program
檔案中使用對 UseStaticFiles 的兩個呼叫:- 使用 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 提供來自多個位置的檔案:
- 將 Microsoft.Extensions.FileProviders 的命名空間新增至伺服器專案的
Program
檔案頂端。 - 在呼叫 UseStaticFiles 之前的伺服器專案
Program
檔案中:- 使用靜態資產的路徑建立 PhysicalFileProvider。
- 從 WebRootFileProvider 與 PhysicalFileProvider 建立 CompositeFileProvider。 將複合檔案提供者指派回應用程式的 WebRootFileProvider。
範例:
在名為 AdditionalStaticAssets
的伺服器專案中建立新資料夾。 將影像放入資料夾中。
將下列 using
陳述式新增至伺服器專案的 Program
檔案頂端:
using Microsoft.Extensions.FileProviders;
在呼叫 UseStaticFiles 之前的伺服器專案 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}
預留位置是影像替代文字。
執行應用程式。