Układ wdrożenia aplikacji ASP.NET Core hostowanych w Blazor WebAssembly
Uwaga
Nie jest to najnowsza wersja tego artykułu. Aby zapoznać się z aktualnym wydaniem, zobacz wersję tego artykułu dla platformy .NET 9.
Ostrzeżenie
Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz zasady pomocy technicznej platformy .NET i platformy .NET Core. Aby zapoznać się z aktualnym wydaniem, zobacz wersję tego artykułu dla platformy .NET 9.
Ważne
Te informacje odnoszą się do produktu w wersji wstępnej, który może zostać znacząco zmodyfikowany, zanim zostanie wydany komercyjnie. Firma Microsoft nie udziela żadnych gwarancji, wyraźnych ani domniemanych, w odniesieniu do podanych tutaj informacji.
Aby zapoznać się z aktualnym wydaniem, zobacz wersję tego artykułu dla platformy .NET 9.
W tym artykule wyjaśniono, jak włączyć Blazor WebAssembly hostowane wdrożenia w środowiskach, które blokują pobieranie i wykonywanie plików biblioteki DLL.
Uwaga
Te wskazówki dotyczą środowisk, które blokują klientom pobieranie i wykonywanie bibliotek DLL. W programie .NET 8 lub nowszym Blazor format pliku Webcil jest używany do rozwiązania tego problemu. Aby uzyskać więcej informacji, zobacz Host and deploy ASP.NET Core Blazor WebAssembly. Tworzenie pakietów wielopartowych przy użyciu eksperymentalnego pakietu NuGet opisanego w tym artykule nie jest obsługiwane w przypadku Blazor aplikacji na platformie .NET 8 lub nowszej. Skorzystaj ze wskazówek w tym artykule, aby utworzyć własny wieloczęściowy pakiet NuGet dla platformy .NET 8 lub nowszej.
Blazor WebAssembly aplikacje wymagają, aby biblioteki linków dynamicznych (DLL) działały, ale niektóre środowiska blokują klientom pobieranie i wykonywanie bibliotek DLL. W podzestawie tych środowisk zmiana rozszerzenia nazwy pliku plików DLL (.dll
) jest wystarczająca do obejścia ograniczeń zabezpieczeń, ale produkty zabezpieczeń są często w stanie skanować zawartość plików przechodzących przez sieć i zablokować lub poddać kwarantannie pliki DLL. W tym artykule opisano jedno podejście do włączania aplikacji Blazor WebAssembly w tych środowiskach, gdzie tworzony jest plik pakietu wieloczęściowego z bibliotek DLL aplikacji, aby można było je pobrać razem, omijając ograniczenia zabezpieczeń.
Blazor WebAssembly Hostowana aplikacja może dostosować opublikowane pliki i pakowanie bibliotek DLL aplikacji przy użyciu następujących funkcji:
- Inicjatory języka JavaScript , które umożliwiają dostosowywanie procesu rozruchu Blazor .
- Rozszerzalność programu MSBuild w celu przekształcenia listy opublikowanych plików i zdefiniowania Blazor rozszerzeń publikowania. Blazor Rozszerzenia publikowania to pliki zdefiniowane podczas procesu publikowania, które stanowią alternatywną reprezentację zestawu plików wymaganych do uruchomienia opublikowanej Blazor WebAssembly aplikacji. W tym artykule utworzone jest rozszerzenie publikowania Blazor, które generuje pakiet wieloczęściowy zawierający wszystkie biblioteki DLL aplikacji zapakowane w jeden plik, co pozwala na pobranie wszystkich bibliotek DLL razem.
Podejście przedstawione w tym artykule służy jako punkt wyjścia dla deweloperów do opracowania własnych strategii i niestandardowych procesów ładowania.
Ostrzeżenie
Każde podejście podjęte w celu obejścia ograniczenia bezpieczeństwa musi być starannie przemyślane pod kątem jego skutków dla bezpieczeństwa. Zalecamy dalsze zapoznanie się z tematem u specjalistów ds. zabezpieczeń sieci w organizacji przed przyjęciem podejścia w tym artykule. Alternatywy do rozważenia:
- Włącz urządzenia zabezpieczające i oprogramowanie zabezpieczające, aby umożliwić klientom sieciowym pobieranie i używanie dokładnych plików wymaganych przez aplikację Blazor WebAssembly .
- Przełącz się z modelu hostingu Blazor WebAssembly do modelu hostinguBlazor Server, który obsługuje cały kod języka C# aplikacji na serwerze i nie wymaga pobierania bibliotek DLL do klientów. Blazor Server Oferuje również możliwość zachowania prywatności kodu w języku C# bez konieczności używania aplikacji web API w aplikacjach Blazor WebAssembly.
Eksperymentalny pakiet NuGet i przykładowa aplikacja
Podejście opisane w tym artykule jest używane przez pakiet eksperymentalnyMicrosoft.AspNetCore.Components.WebAssembly.MultipartBundle
(NuGet.org) dla aplikacji przeznaczonych dla platformy .NET 6 lub nowszej. Pakiet zawiera elementy docelowe programu MSBuild, aby dostosować Blazor wyniki publikacji i inicjator języka JavaScript do używania niestandardowego modułu ładującego zasoby rozruchowe, z których każdy został szczegółowo opisany w dalszej części artykułu.
Ostrzeżenie
Funkcje eksperymentalne i w wersji zapoznawczej są udostępniane na potrzeby zbierania opinii i nie są obsługiwane w środowisku produkcyjnym.
W dalszej części tego artykułu sekcja Dostosowywanie Blazor WebAssembly procesu ładowania za pośrednictwem pakietu NuGet wraz z trzema podsekcjami zawiera szczegółowe wyjaśnienia dotyczące konfiguracji i kodu w Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
pakiecie. Szczegółowe wyjaśnienia są ważne, aby zrozumieć, kiedy tworzysz własną strategię i niestandardowy proces ładowania aplikacji Blazor WebAssembly . Aby użyć opublikowanego, eksperymentalnego, nieobsługiwanego pakietu NuGet bez dostosowywania jako pokazu lokalnego, wykonaj następujące kroki:
Użyj istniejącego hostowanego Blazor WebAssemblyrozwiązania lub utwórz nowe rozwiązanie na podstawie szablonu projektu Blazor WebAssembly przy użyciu programu Visual Studio lub przez przekazanie opcji
-ho|--hosted
do poleceniadotnet new
(dotnet new blazorwasm -ho
). Aby uzyskać więcej informacji, zobacz Tooling for ASP.NET Core Blazor.W projekcie Client dodaj pakiet eksperymentalny
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
.Uwaga
Aby uzyskać wskazówki dotyczące dodawania pakietów do aplikacji .NET, zobacz artykuły w Instalowanie i zarządzanie pakietami oraz w proces korzystania z pakietów (dokumentacja NuGet). Sprawdź prawidłowe wersje pakietów pod adresem NuGet.org.
W projekcie Server dodaj punkt końcowy służący do obsługi pliku pakietu (
app.bundle
). Przykładowy kod można znaleźć w sekcji Obsługa pakietu w sekcji aplikacji serwera hosta w tym artykule.Opublikuj aplikację w konfiguracji wydania.
Blazor WebAssembly Dostosowywanie procesu ładowania za pomocą pakietu NuGet
Ostrzeżenie
Wskazówki zawarte w tej sekcji z trzema podsekcjami dotyczą tworzenia pakietu NuGet od podstaw w celu zaimplementowania własnej strategii i niestandardowego procesu ładowania. Pakiet eksperymentalnyMicrosoft.AspNetCore.Components.WebAssembly.MultipartBundle
(NuGet.org) dla platformy .NET 6 i 7 jest oparty na wskazówkach w tej sekcji. W przypadku korzystania z podanego pakietu w lokalnym pokazie podejścia do pobierania pakietów wieloczęściowych nie trzeba postępować zgodnie ze wskazówkami w tej sekcji. Aby uzyskać wskazówki dotyczące korzystania z podanego pakietu, zobacz sekcję Eksperymentalny pakiet NuGet i przykładową aplikację .
Blazorzasoby aplikacji są pakowane do pliku pakietu wieloczęściowego i ładowane przez przeglądarkę za pośrednictwem niestandardowego inicjatora języka JavaScript (JS). W przypadku aplikacji korzystającej z pakietu za pomocą inicjatora JS, aplikacja wymaga jedynie, aby plik pakietu był udostępniany na żądanie. Wszystkie inne aspekty tego podejścia są obsługiwane w sposób przejrzysty.
Do sposobu ładowania domyślnej opublikowanej Blazor aplikacji są wymagane cztery dostosowania:
- Zadanie MSBuild do przekształcania plików do publikacji.
- Pakiet NuGet z elementami docelowymi programu MSBuild, który łączy się w Blazor proces publikowania, przekształca dane wyjściowe i definiuje co najmniej jeden Blazor plik rozszerzenia publikowania (w tym przypadku pojedynczy pakiet).
- Inicjalizator JS do zaktualizowania wywołania zwrotnego Blazor WebAssembly ładującego zasoby, aby załadować pakiet i zapewnić aplikacji dostęp do poszczególnych plików.
- Pomocnik w aplikacji hosta Server, które zapewnia, że pakiet jest dostarczany klientom na żądanie.
Tworzenie zadania MSBuild w celu dostosowania listy opublikowanych plików i zdefiniowania nowych rozszerzeń
Utwórz zadanie MSBuild jako publiczną klasę języka C#, którą można zaimportować w ramach kompilacji MSBuild i która może współdziałać z kompilacją.
Dla klasy C# wymagane są następujące elementy:
- Nowy projekt biblioteki klas.
- Struktura docelowa projektu .
netstandard2.0
- Odwołania do pakietów MSBuild:
Uwaga
Pakiet NuGet dla przykładów w tym artykule nosi nazwę po pakiecie dostarczonym przez firmę Microsoft, Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
. Aby uzyskać wskazówki dotyczące nazewnictwa i tworzenia własnego pakietu NuGet, zobacz następujące artykuły NuGet:
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks/Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks.csproj
:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Build.Framework" Version="{VERSION}" />
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="{VERSION}" />
</ItemGroup>
</Project>
Określ najnowsze wersje pakietów dla {VERSION}
symboli zastępczych w NuGet.org:
Aby utworzyć zadanie MSBuild, utwórz publiczną klasę języka C# rozszerzającą Microsoft.Build.Utilities.Task (a nie System.Threading.Tasks.Task) i zadeklaruj trzy właściwości:
-
PublishBlazorBootStaticWebAsset
: lista plików do opublikowania dla aplikacji Blazor. -
BundlePath
: ścieżka, w której jest zapisywany pakiet. -
Extension
: nowe rozszerzenia publikowania do uwzględnienia w kompilacji.
Poniższa przykładowa BundleBlazorAssets
klasa to punkt wyjścia do dalszego dostosowywania:
- W metodzie
Execute
pakiet jest tworzony na podstawie następujących trzech typów plików:- Pliki JavaScript (
dotnet.js
) - Pliki WASM (
dotnet.wasm
) - Biblioteki DLL aplikacji (
.dll
)
- Pliki JavaScript (
- Tworzony jest
multipart/form-data
pakiet. Każdy plik jest dodawany do pakietu z odpowiednimi opisami za pośrednictwem nagłówka Content-Disposition i nagłówka Content-Type. - Po utworzeniu pakietu pakiet jest zapisywany w pliku.
- Kompilacja jest skonfigurowana dla rozszerzenia. Poniższy kod tworzy element rozszerzenia i dodaje go do
Extension
właściwości . Każdy element rozszerzenia zawiera trzy fragmenty danych:- Ścieżka do pliku rozszerzenia.
- Ścieżka adresu URL względem katalogu głównego Blazor WebAssembly aplikacji.
- Nazwa rozszerzenia, które grupuje pliki utworzone przez określone rozszerzenie.
Po osiągnięciu wcześniejszych celów zadanie MSBuild jest tworzone do customizacji danych wyjściowych publikacji Blazor.
Blazor dba o gromadzenie rozszerzeń i zapewnia, że są one kopiowane do właściwej lokalizacji w folderze danych wyjściowych publikacji (na przykład bin\Release\net6.0\publish
). Te same optymalizacje (na przykład kompresja) są stosowane do plików JavaScript, WASM i DLL w taki sam sposób, w jaki Blazor są stosowane do innych plików.
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks/BundleBlazorAssets.cs
:
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks
{
public class BundleBlazorAssets : Task
{
[Required]
public ITaskItem[]? PublishBlazorBootStaticWebAsset { get; set; }
[Required]
public string? BundlePath { get; set; }
[Output]
public ITaskItem[]? Extension { get; set; }
public override bool Execute()
{
var bundle = new MultipartFormDataContent(
"--0a7e8441d64b4bf89086b85e59523b7d");
foreach (var asset in PublishBlazorBootStaticWebAsset)
{
var name = Path.GetFileName(asset.GetMetadata("RelativePath"));
var fileContents = File.OpenRead(asset.ItemSpec);
var content = new StreamContent(fileContents);
var disposition = new ContentDispositionHeaderValue("form-data");
disposition.Name = name;
disposition.FileName = name;
content.Headers.ContentDisposition = disposition;
var contentType = Path.GetExtension(name) switch
{
".js" => "text/javascript",
".wasm" => "application/wasm",
_ => "application/octet-stream"
};
content.Headers.ContentType =
MediaTypeHeaderValue.Parse(contentType);
bundle.Add(content);
}
using (var output = File.Open(BundlePath, FileMode.OpenOrCreate))
{
output.SetLength(0);
bundle.CopyToAsync(output).ConfigureAwait(false).GetAwaiter()
.GetResult();
output.Flush(true);
}
var bundleItem = new TaskItem(BundlePath);
bundleItem.SetMetadata("RelativePath", "app.bundle");
bundleItem.SetMetadata("ExtensionName", "multipart");
Extension = new ITaskItem[] { bundleItem };
return true;
}
}
}
Twórz pakiet NuGet, aby automatycznie przekształcać wyniki publikowania
Wygeneruj pakiet NuGet z miejscami docelowymi programu MSBuild, które są automatycznie dołączane po odwołaniu do pakietu:
- Utwórz nowy Razor projekt biblioteki klas (RCL).
- Utwórz plik targets zgodnie z konwencjami NuGet, aby automatycznie importować pakiet w projektach, które go używają. Na przykład utwórz
build\net6.0\{PACKAGE ID}.targets
, gdzie{PACKAGE ID}
jest identyfikatorem pakietu. - Zbierz dane wyjściowe z biblioteki klas zawierającej zadanie MSBuild i upewnij się, że dane wyjściowe są pakowane we właściwej lokalizacji.
- Dodaj niezbędny kod MSBuild do połączenia z potokiem Blazor i wywołaj zadanie MSBuild w celu wygenerowania pakietu.
Podejście opisane w tej sekcji używa tylko pakietu do dostarczania elementów docelowych i zawartości, która różni się od większości pakietów, w których pakiet zawiera bibliotekę DLL.
Ostrzeżenie
Przykładowy pakiet opisany w tej sekcji przedstawia sposób dostosowywania procesu publikowania Blazor . Przykładowy pakiet NuGet jest używany tylko jako lokalny pokaz. Używanie tego pakietu w środowisku produkcyjnym nie jest obsługiwane.
Uwaga
Pakiet NuGet dla przykładów w tym artykule nosi nazwę po pakiecie dostarczonym przez firmę Microsoft, Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
. Aby uzyskać wskazówki dotyczące nazewnictwa i tworzenia własnego pakietu NuGet, zobacz następujące artykuły NuGet:
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle/Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.csproj
:
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<NoWarn>NU5100</NoWarn>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Description>
Sample demonstration package showing how to customize the Blazor publish
process. Using this package in production is not supported!
</Description>
<IsPackable>true</IsPackable>
<IsShipping>true</IsShipping>
<IncludeBuildOutput>false</IncludeBuildOutput>
</PropertyGroup>
<ItemGroup>
<None Update="build\**"
Pack="true"
PackagePath="%(Identity)" />
<Content Include="_._"
Pack="true"
PackagePath="lib\net6.0\_._" />
</ItemGroup>
<Target Name="GetTasksOutputDlls"
BeforeTargets="CoreCompile">
<MSBuild Projects="..\Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks\Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks.csproj"
Targets="Publish;PublishItemsOutputGroup"
Properties="Configuration=Release">
<Output TaskParameter="TargetOutputs"
ItemName="_TasksProjectOutputs" />
</MSBuild>
<ItemGroup>
<Content Include="@(_TasksProjectOutputs)"
Condition="'%(_TasksProjectOutputs.Extension)' == '.dll'"
Pack="true"
PackagePath="tasks\%(_TasksProjectOutputs.TargetPath)"
KeepMetadata="Pack;PackagePath" />
</ItemGroup>
</Target>
</Project>
Uwaga
Właściwość <NoWarn>NU5100</NoWarn>
w poprzednim przykładzie pomija ostrzeżenie dotyczące zestawów umieszczonych w folderze tasks
. Aby uzyskać więcej informacji, zobacz Ostrzeżenie narzędzia NuGet NU5100.
Dodaj plik .targets
aby połączyć zadanie MSBuild z potokiem kompilacji. W tym pliku są realizowane następujące cele:
- Zaimportuj zadanie do procesu kompilacji. Należy pamiętać, że ścieżka do biblioteki DLL jest względna względem ostatecznej lokalizacji pliku w pakiecie.
- Właściwość
ComputeBlazorExtensionsDependsOn
dołącza niestandardowy element docelowy do potoku Blazor WebAssembly. -
Extension
Przechwyć właściwość w danych wyjściowych zadania i dodaj ją, aby poinformowaćBlazorPublishExtension
Blazor o rozszerzeniu. Wywołanie zadania w obiekcie docelowym powoduje wygenerowanie pakietu. Lista opublikowanych plików jest dostarczana przez Blazor WebAssembly pipeline wPublishBlazorBootStaticWebAsset
grupie elementu. Ścieżka pakietu jest definiowana przy użyciuIntermediateOutputPath
(zazwyczaj wewnątrz folderuobj
). Ostatecznie pakiet jest kopiowany automatycznie do docelowej lokalizacji w folderze wynikowym publikacji (na przykładbin\Release\net6.0\publish
).
Po odwołaniu się do pakietu, podczas publikowania generuje zestaw plików Blazor.
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle/build/net6.0/Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.targets
:
<Project>
<UsingTask
TaskName="Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks.BundleBlazorAssets"
AssemblyFile="$(MSBuildThisProjectFileDirectory)..\..\tasks\Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.Tasks.dll" />
<PropertyGroup>
<ComputeBlazorExtensionsDependsOn>
$(ComputeBlazorExtensionsDependsOn);_BundleBlazorDlls
</ComputeBlazorExtensionsDependsOn>
</PropertyGroup>
<Target Name="_BundleBlazorDlls">
<BundleBlazorAssets
PublishBlazorBootStaticWebAsset="@(PublishBlazorBootStaticWebAsset)"
BundlePath="$(IntermediateOutputPath)bundle.multipart">
<Output TaskParameter="Extension"
ItemName="BlazorPublishExtension"/>
</BundleBlazorAssets>
</Target>
</Project>
Automatyczne uruchamianie Blazor z pakietu
Pakiet NuGet wykorzystuje inicjatory języka JavaScript (JS), aby automatycznie uruchamiać aplikację Blazor WebAssembly z pakietu zamiast używać pojedynczych plików DLL. JSInicjalizatory są używane do zmiany Blazormodułu ładującego zasób rozruchowy oraz używania zbioru.
Aby utworzyć JS inicjator, dodaj JS plik o nazwie {NAME}.lib.module.js
do wwwroot
folderu projektu pakietu, gdzie {NAME}
symbol zastępczy jest identyfikatorem pakietu. Na przykład plik pakietu firmy Microsoft ma nazwę Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.lib.module.js
. Wyeksportowane funkcje beforeWebAssemblyStart
i afterWebAssemblyStarted
obsługują ładowanie.
Inicjatory JS :
- Sprawdź, czy dostępne jest rozszerzenie publikowania, poprzez detekcję
extensions.multipart
, czyli nazwy rozszerzenia (ExtensionName
) podanej w sekcji Tworzenie zadania MSBuild w celu dostosowania listy opublikowanych plików i zdefiniowania nowych rozszerzeń. - Pobierz pakiet i przeanalizuj zawartość na mapie zasobów przy użyciu wygenerowanych adresów URL obiektów.
- Zaktualizuj moduł ładujący zasobów rozruchowych (
options.loadBootResource
) za pomocą funkcji niestandardowej, która rozpoznaje zasoby przy użyciu adresów URL obiektów. - Po uruchomieniu aplikacji odwołaj adresy URL obiektów, aby zwolnić pamięć w
afterWebAssemblyStarted
funkcji.
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle/wwwroot/Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.lib.module.js
:
const resources = new Map();
export async function beforeWebAssemblyStart(options, extensions) {
if (!extensions || !extensions.multipart) {
return;
}
try {
const integrity = extensions.multipart['app.bundle'];
const bundleResponse =
await fetch('app.bundle', { integrity: integrity, cache: 'no-cache' });
const bundleFromData = await bundleResponse.formData();
for (let value of bundleFromData.values()) {
resources.set(value, URL.createObjectURL(value));
}
options.loadBootResource = function (type, name, defaultUri, integrity) {
return resources.get(name) ?? null;
}
} catch (error) {
console.log(error);
}
}
export async function afterWebAssemblyStarted(blazor) {
for (const [_, url] of resources) {
URL.revokeObjectURL(url);
}
}
Aby utworzyć JS inicjator, dodaj JS plik o nazwie {NAME}.lib.module.js
do wwwroot
folderu projektu pakietu, gdzie {NAME}
symbol zastępczy jest identyfikatorem pakietu. Na przykład plik pakietu firmy Microsoft ma nazwę Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.lib.module.js
. Wyeksportowane funkcje beforeStart
i afterStarted
obsługa ładowania.
Inicjatory JS :
- Sprawdź, czy rozszerzenie Publish jest dostępne, sprawdzając
extensions.multipart
nazwę rozszerzenia (ExtensionName
) podaną w zadaniu tworzenia programu MSBuild, aby dostosować listę opublikowanych plików i zdefiniować nowe rozszerzenia. - Pobierz pakiet i przeanalizuj zawartość na mapie zasobów przy użyciu wygenerowanych adresów URL obiektów.
- Zaktualizuj moduł ładujący zasobów rozruchowych (
options.loadBootResource
) za pomocą funkcji niestandardowej, która rozpoznaje zasoby przy użyciu adresów URL obiektów. - Po uruchomieniu aplikacji odwołaj adresy URL obiektów, aby zwolnić pamięć w
afterStarted
funkcji.
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle/wwwroot/Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.lib.module.js
:
const resources = new Map();
export async function beforeStart(options, extensions) {
if (!extensions || !extensions.multipart) {
return;
}
try {
const integrity = extensions.multipart['app.bundle'];
const bundleResponse =
await fetch('app.bundle', { integrity: integrity, cache: 'no-cache' });
const bundleFromData = await bundleResponse.formData();
for (let value of bundleFromData.values()) {
resources.set(value, URL.createObjectURL(value));
}
options.loadBootResource = function (type, name, defaultUri, integrity) {
return resources.get(name) ?? null;
}
} catch (error) {
console.log(error);
}
}
export async function afterStarted(blazor) {
for (const [_, url] of resources) {
URL.revokeObjectURL(url);
}
}
Obsługa pakietu z aplikacji serwera hosta
Ze względu na ograniczenia zabezpieczeń ASP.NET Core nie obsługuje app.bundle
pliku. Pomocnik przetwarzania żądań jest wymagany do obsługi pliku, gdy jest on żądany przez klientów.
Uwaga
Ponieważ te same optymalizacje są przezroczysto stosowane do rozszerzeń publikowania, co do plików aplikacji, skompresowane pliki zasobów app.bundle.gz
i app.bundle.br
są generowane automatycznie podczas publikowania.
Umieść kod C# w projekcie Server bezpośrednio przed wierszem, który ustawia plik zapasowy na index.html
(app.MapFallbackToFile("index.html");
), aby odpowiedzieć na żądanie dla pliku pakietu (na przykład app.bundle
):
app.MapGet("app.bundle", (HttpContext context) =>
{
string? contentEncoding = null;
var contentType =
"multipart/form-data; boundary=\"--0a7e8441d64b4bf89086b85e59523b7d\"";
var fileName = "app.bundle";
var acceptEncodings = context.Request.Headers.AcceptEncoding;
if (Microsoft.Net.Http.Headers.StringWithQualityHeaderValue
.StringWithQualityHeaderValue
.TryParseList(acceptEncodings, out var encodings))
{
if (encodings.Any(e => e.Value == "br"))
{
contentEncoding = "br";
fileName += ".br";
}
else if (encodings.Any(e => e.Value == "gzip"))
{
contentEncoding = "gzip";
fileName += ".gz";
}
}
if (contentEncoding != null)
{
context.Response.Headers.ContentEncoding = contentEncoding;
}
return Results.File(
app.Environment.WebRootFileProvider.GetFileInfo(fileName)
.CreateReadStream(), contentType);
});
Typ zawartości jest zgodny z typem zdefiniowanym wcześniej w zadaniu kompilacji. Punkt końcowy sprawdza kodowanie zawartości akceptowane przez przeglądarkę i obsługuje optymalny plik, Brotli (.br
) lub Gzip (.gz
).