비고
이 기사는 최신 버전이 아닙니다. 현재 릴리스에 대해서는 본 기사의 .NET 9 버전을 참조하십시오.
경고
이 버전의 ASP.NET Core는 더 이상 지원되지 않습니다. 자세한 내용은 .NET 및 .NET Core 지원 정책을 참조하세요. 현재 릴리스에 대해서는 본 기사의 .NET 9 버전을 참조하십시오.
중요합니다
이 정보는 사전 출시 제품과 관련이 있으며, 상업적으로 출시되기 전에 상당히 수정될 수 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
현재 릴리스에 대해서는 본 기사의 .NET 9 버전을 참조하십시오.
이 문서에서는 DLL(동적 연결 라이브러리) 파일의 다운로드 및 실행을 차단하는 환경에서 호스팅 Blazor WebAssembly 된 배포를 사용하도록 설정하는 방법을 설명합니다.
비고
이 지침은 클라이언트가 DLL을 다운로드하고 실행하지 못하도록 차단하는 환경을 다룹니다. .NET 8 이상 Blazor 에서는 웹실 파일 형식을 사용하여 이 문제를 해결합니다. 자세한 내용은 ASP.NET Core Blazor WebAssembly 호스트 및 배포를 참조하세요. 이 문서에서 설명하는 실험적 NuGet 패키지를 사용하는 멀티파트 번들링은 .NET 8 이상의 앱에서는 Blazor 지원되지 않습니다. 이 문서의 지침을 사용하여 .NET 8 이상용 고유한 멀티파트 번들링 NuGet 패키지를 만들 수 있습니다.
Blazor WebAssembly 앱이 작동하려면 DLL(동적 연결 라이브러리)이 필요하지만 일부 환경에서는 클라이언트가 DLL을 다운로드하고 실행할 수 없습니다. 보안 제품은 종종 네트워크를 통과하는 파일의 내용을 검사하고 DLL 파일을 차단하거나 격리할 수 있습니다. 이 문서에서는 보안 제한을 우회하여 DLL을 함께 다운로드할 수 있도록 앱의 DLL에서 멀티파트 번들 파일이 만들어지는 이러한 환경에서 앱을 사용하도록 설정하는 Blazor WebAssembly 한 가지 방법을 설명합니다.
Blazor WebAssembly 앱이 작동하려면 DLL(동적 연결 라이브러리)이 필요하지만 일부 환경에서는 클라이언트가 DLL을 다운로드하고 실행할 수 없습니다. 이러한 환경의 하위 집합에서는 DLL 파일(.dll
)의 파일 이름 확장명을 변경하는 것만 으로도 보안 제한을 우회할 수 있지만 보안 제품은 네트워크를 통과하는 파일의 내용을 검사하고 DLL 파일을 차단하거나 격리할 수 있는 경우가 많습니다. 이 문서에서는 보안 제한을 우회하여 DLL을 함께 다운로드할 수 있도록 앱의 DLL에서 멀티파트 번들 파일이 만들어지는 이러한 환경에서 앱을 사용하도록 설정하는 Blazor WebAssembly 한 가지 방법을 설명합니다.
호스팅 Blazor WebAssembly 된 앱은 다음 기능을 사용하여 게시된 파일 및 앱 DLL의 패키징을 사용자 지정할 수 있습니다.
- 부팅 프로세스를 사용자 지정할 수 있는 JavaScript 이니셜라이저입니다Blazor.
- 게시된 파일 목록을 변환하고 게시 확장을 정의Blazor하기 위한 MSBuild 확장성. Blazor 게시 확장은 게시된 Blazor WebAssembly 앱을 실행하는 데 필요한 파일 집합에 대한 대체 표현을 제공하는 게시 프로세스 중에 정의된 파일입니다. 이 문서에서는 Blazor DLL을 함께 다운로드할 수 있도록 앱의 모든 DLL이 단일 파일로 압축된 멀티파트 번들을 생성하는 게시 확장을 만듭니다.
이 문서에서 설명하는 방법은 개발자가 자신의 전략과 사용자 지정 로드 프로세스를 고안할 수 있는 시작점 역할을 합니다.
경고
보안 제한을 우회하기 위해 취하는 모든 접근 방식은 보안에 미치는 영향을 신중하게 고려해야 합니다. 이 문서의 접근 방식을 채택하기 전에 조직의 네트워크 보안 전문가와 함께 이 주제를 자세히 살펴보는 것이 좋습니다. 고려해야 할 대안은 다음과 같습니다.
- 보안 어플라이언스 및 보안 소프트웨어를 사용하여 네트워크 클라이언트가 앱에 필요한 정확한 파일을 다운로드하고 사용할 수 있도록 Blazor WebAssembly 합니다.
- Blazor WebAssembly 호스팅 모델에서 호스팅 모델로Blazor Server 전환하면 서버에서 앱의 모든 C# 코드가 유지 관리되고 DLL을 클라이언트에 다운로드할 필요가 없습니다. Blazor Server 또한 앱에서 C# 코드 개인 정보 보호를 위해 웹 API 앱을 사용할 필요 없이 C# 코드를 비공개로 유지할 수 있는 Blazor WebAssembly 이점을 제공합니다.
실험적 NuGet 패키지 및 샘플 앱
이 문서에 설명된 방법은 .NET 6 이상을 대상으로 하는 앱의 NuGet.org( 실험적Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
패키지) 에서 사용됩니다. 패키지에는 게시 출력을 사용자 지정 Blazor 하기 위한 MSBuild 대상과 사용자 지정 부팅 리소스 로더를 사용하도록 JavaScript 이니셜라이저가 포함되어 있으며, 각각은 이 문서의 뒷부분에 자세히 설명되어 있습니다.
경고
실험적 및 미리 보기 기능은 피드백을 수집하기 위해 제공되며 프로덕션 용도로는 지원되지 않습니다.
이 문서의 뒷부분에 있는 세 개의 하위 섹션이 있는 NuGet 패키지를 통해 로드 프로세스 사용자 지정 Blazor WebAssembly 섹션에서는 패키지의 구성 및 코드에 Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
대한 자세한 설명을 제공합니다. 자세한 설명은 앱에 대한 Blazor WebAssembly 고유한 전략 및 사용자 지정 로드 프로세스를 만들 때 이해하는 것이 중요합니다. 사용자 지정 없이 게시된 실험적이고 지원되지 않는 NuGet 패키지를 로컬 데모로 사용하려면 다음 단계를 수행합니다.
기존 호스팅 Blazor WebAssembly 된 솔루션을 사용하거나 Visual Studio를 사용하거나 ()Blazor WebAssembly 명령에 옵션을 전달
-ho|--hosted
하여 프로젝트 템플릿에서dotnet new
새 솔루션을 만듭니다.dotnet new blazorwasm -ho
자세한 내용은 ASP.NET Core용 도구를 참조하세요 Blazor.Client 프로젝트에서 실험적
Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
패키지를 추가합니다.비고
.NET 앱에 패키지를 추가하는 방법에 대한 지침은 패키지 사용 작업 흐름(NuGet 문서)의 패키지 설치 및 관리 섹션에서 확인할 수 있습니다. 올바른 패키지 버전을 NuGet.org에서 확인하세요.
Server 프로젝트에서 번들 파일()
app.bundle
을 제공하기 위한 엔드포인트를 추가합니다. 예제 코드는 이 문서의 호스트 서버 앱에서 번들 제공 섹션에서 찾을 수 있습니다.릴리스 구성에 앱을 게시합니다.
NuGet 패키지를 통해 로딩 프로세스 사용자 지정Customize the Blazor WebAssembly loading process via a NuGet package
경고
세 개의 하위 섹션이 있는 이 섹션의 지침은 고유한 전략 및 사용자 지정 로드 프로세스를 구현하기 위해 처음부터 NuGet 패키지를 빌드하는 것과 관련이 있습니다. .NET 6 및 7에 대한 NuGet.org(실험적Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
패키지) 는 이 섹션의 지침을 기반으로 합니다. 멀티파트 번들 다운로드 방법의 로컬 데모 에서 제공된 패키지를 사용하는 경우 이 섹션의 지침을 따를 필요가 없습니다. 제공된 패키지를 사용하는 방법에 대한 지침은 실험적 NuGet 패키지 및 샘플 앱 섹션을 참조하세요.
Blazor 앱 리소스는 멀티파트 번들 파일로 압축되고 사용자 지정 JavaScript(JS) 이니셜라이저를 통해 브라우저에 의해 로드됩니다. 이니셜라이저와 함께 JS 패키지를 사용하는 앱의 경우 앱은 요청 시 번들 파일만 제공하면 됩니다. 이 방법의 다른 모든 측면은 투명하게 처리됩니다.
기본 게시된 Blazor 앱을 로드하는 방법에는 4가지 사용자 지정이 필요합니다.
- 게시 파일을 변환하는 MSBuild 작업입니다.
- 게시 프로세스에 연결 Blazor 하고, 출력을 변환하고, 하나 이상의 Blazor 게시 확장 파일(이 경우 단일 번들)을 정의하는 MSBuild 대상이 있는 NuGet 패키지입니다.
- JS 리소스 로더 콜백을 Blazor WebAssembly 업데이트하여 번들을 로드하고 앱에 개별 파일을 제공하는 이니셜라이저입니다.
- 요청 시 번들이 클라이언트에 제공되도록 하는 호스트 Server 앱의 도우미입니다.
MSBuild 작업을 만들어 게시된 파일 목록을 사용자 지정하고 새 확장명을 정의합니다
MSBuild 컴파일의 일부로 가져올 수 있고 빌드와 상호 작용할 수 있는 공용 C# 클래스로 MSBuild 작업을 만듭니다.
C# 클래스에는 다음이 필요합니다.
- 새 클래스 라이브러리 프로젝트입니다.
- 의
netstandard2.0
프로젝트 대상 프레임워크입니다. - MSBuild 패키지에 대한 참조:
비고
이 문서의 예제에 대한 NuGet 패키지는 Microsoft Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
에서 제공하는 패키지의 이름을 따서 명명되었습니다. 사용자 고유의 NuGet 패키지 이름을 지정하고 생성하는 방법에 대한 지침은 다음 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>
NuGet.org 에서 자리 표시자에 대한 {VERSION}
최신 패키지 버전을 확인합니다.
MSBuild 작업을 만들려면 확장(not Microsoft.Build.Utilities.Task)하는 공용 C# 클래스를 System.Threading.Tasks.Task 만들고 세 가지 속성을 선언합니다.
-
PublishBlazorBootStaticWebAsset
: 앱용으로 Blazor 게시할 파일 목록입니다. -
BundlePath
: 번들이 작성되는 경로입니다. -
Extension
: 빌드에 포함할 새 게시 확장입니다.
다음 예제 BundleBlazorAssets
클래스는 추가 사용자 지정을 위한 시작점입니다.
- 이
Execute
메서드에서 번들은 다음 세 가지 파일 형식으로 만들어집니다.- 자바스크립트 파일(
dotnet.js
) - WASM 파일 ()
dotnet.wasm
- 앱 DLL(
.dll
)
- 자바스크립트 파일(
- 번들이
multipart/form-data
만들어집니다. 각 파일은 Content-Disposition 헤더 및 Content-Type 헤더를 통해 해당 설명과 함께 번들에 추가됩니다. - 번들이 만들어지면 번들이 파일에 기록됩니다.
- 빌드는 확장에 대해 구성됩니다. 다음 코드는 확장 항목을 만들어 속성에 추가합니다
Extension
. 각 확장 항목에는 세 가지 데이터가 포함됩니다.- 확장 파일의 경로입니다.
- 앱의 루트를 기준으로 하는 URL 경로입니다 Blazor WebAssembly .
- 지정된 확장에서 생성된 파일을 그룹화하는 확장의 이름입니다.
앞의 목표를 달성한 후 게시 출력을 사용자 지정 Blazor 하기 위한 MSBuild 작업이 만들어집니다.
Blazor 에서는 확장 프로그램을 수집하고 확장 프로그램이 게시 출력 폴더의 올바른 위치(예: bin\Release\net6.0\publish
)에 복사되었는지 확인합니다. 다른 파일에 적용되는 것과 동일한 Blazor 최적화(예: 압축)가 JavaScript, WASM 및 DLL 파일에 적용됩니다.
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;
}
}
}
NuGet 패키지를 작성하여 게시 출력을 자동으로 변환합니다.
패키지가 참조될 때 자동으로 포함되는 MSBuild 대상을 사용하여 NuGet 패키지를 생성합니다.
- 새Razor RCL(클래스 라이브러리) 프로젝트를 만듭니다.
- NuGet 규칙에 따라 대상 파일을 만들어 사용 프로젝트에서 패키지를 자동으로 가져옵니다. 예를 들어, create
build\net6.0\{PACKAGE ID}.targets
는{PACKAGE ID}
패키지의 패키지 식별자입니다. - MSBuild 작업이 포함된 클래스 라이브러리에서 출력을 수집하고 출력이 올바른 위치에 압축되어 있는지 확인합니다.
- 파이프라인에 연결하는 Blazor 데 필요한 MSBuild 코드를 추가하고 MSBuild 작업을 호출하여 번들을 생성합니다.
이 섹션에서 설명하는 방법은 패키지를 사용하여 대상과 콘텐츠를 전달하는 데만 사용되며, 이는 패키지에 라이브러리 DLL이 포함된 대부분의 패키지와 다릅니다.
경고
이 섹션에 설명된 샘플 패키지는 게시 프로세스를 사용자 지정하는 Blazor 방법을 보여 줍니다. 샘플 NuGet 패키지는 로컬 데모로만 사용할 수 있습니다. 프로덕션에서 이 패키지를 사용하는 것은 지원되지 않습니다.
비고
이 문서의 예제에 대한 NuGet 패키지는 Microsoft Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle
에서 제공하는 패키지의 이름을 따서 명명되었습니다. 사용자 고유의 NuGet 패키지 이름을 지정하고 생성하는 방법에 대한 지침은 다음 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>
비고
<NoWarn>NU5100</NoWarn>
이전 예제의 속성은 폴더에 배치된 tasks
어셈블리에 대한 경고를 표시하지 않습니다. 자세한 내용은 NuGet 경고 NU5100을 참조하세요.
.targets
MSBuild 작업을 빌드 파이프라인에 연결하는 파일을 추가합니다. 이 파일에서는 다음과 같은 목표를 달성합니다.
- 작업을 빌드 프로세스로 가져옵니다. DLL의 경로는 패키지에 있는 파일의 최종 위치를 기준으로 합니다.
- 이
ComputeBlazorExtensionsDependsOn
속성은 사용자 지정 대상을 파이프라인에 Blazor WebAssembly 연결합니다. - 작업 출력에서
Extension
속성을 캡처하고 확장에 대해 알리BlazorPublishExtension
기 위해 추가합니다Blazor. 대상에서 작업을 호출하면 번들이 생성됩니다. 게시된 파일 목록은 항목 그룹의 파이프라인 Blazor WebAssembly 에서PublishBlazorBootStaticWebAsset
제공됩니다. 번들 경로는 (일반적으로 폴더 내부)를IntermediateOutputPath
사용하여obj
정의됩니다. 궁극적으로 번들은 게시 출력 폴더의 올바른 위치(예:bin\Release\net6.0\publish
)에 자동으로 복사됩니다.
패키지가 참조되면 게시하는 동안 파일 번들이 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>
번들에서 자동으로 부트스트랩 Blazor
NuGet 패키지는 JavaScript(JS) 이니셜라이저 를 활용하여 개별 DLL 파일을 사용하는 대신 번들에서 앱을 자동으로 부트스트랩 Blazor WebAssembly 합니다. JS이니셜라이저는 Blazor를 변경하고 번들을 사용하는 데 사용됩니다.
이니셜라이저를 JS 만들려면 패키지 프로젝트의 폴더에 이름이 JS{NAME}.lib.module.js
있는 파일을 추가합니다wwwroot
. {NAME}
여기서 자리 표시자는 패키지 식별자입니다. 예를 들어 Microsoft 패키지의 파일 이름은 Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.lib.module.js
. 내보낸 함수 beforeWebAssemblyStart
와 afterWebAssemblyStarted
핸들로딩.
이니셜라이저는 다음과 같습니다 JS .
-
extensions.multipart
제공된 확장 이름()ExtensionName
인 를 확인하여 게시 확장을 사용할 수 있는지 확인합니다. - 번들을 다운로드하고 생성된 개체 URL을 사용하여 내용을 리소스 맵으로 구문 분석합니다.
-
boot resource loader (
options.loadBootResource
)를 개체 URL을 사용하여 리소스를 해결하는 사용자 지정 함수로 업데이트합니다. - 앱이 시작된 후 개체 URL을 해지하여 함수의 메모리를 해제합니다
afterWebAssemblyStarted
.
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);
}
}
이니셜라이저를 JS 만들려면 패키지 프로젝트의 폴더에 이름이 JS{NAME}.lib.module.js
있는 파일을 추가합니다wwwroot
. {NAME}
여기서 자리 표시자는 패키지 식별자입니다. 예를 들어 Microsoft 패키지의 파일 이름은 Microsoft.AspNetCore.Components.WebAssembly.MultipartBundle.lib.module.js
. 내보낸 함수 beforeStart
와 afterStarted
핸들로딩.
이니셜라이저는 다음과 같습니다 JS .
-
extensions.multipart
제공된 확장 이름()ExtensionName
인 를 확인하여 게시 확장을 사용할 수 있는지 확인합니다. - 번들을 다운로드하고 생성된 개체 URL을 사용하여 내용을 리소스 맵으로 구문 분석합니다.
-
boot resource loader (
options.loadBootResource
)를 개체 URL을 사용하여 리소스를 해결하는 사용자 지정 함수로 업데이트합니다. - 앱이 시작된 후 개체 URL을 해지하여 함수의 메모리를 해제합니다
afterStarted
.
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);
}
}
호스트 서버 앱에서 번들 제공
보안 제한으로 인해 ASP.NET Core는 app.bundle
파일을 제공하지 않습니다. 요청 처리 도우미는 클라이언트에서 요청할 때 파일을 제공하는 데 필요합니다.
비고
동일한 최적화가 앱의 파일에 app.bundle.gz
적용되는 Publish Extensions에 투명하게 적용되기 때문에 압축 app.bundle.br
된 에셋 파일은 게시 시 자동으로 생성됩니다.
프로젝트의 C# 코드를 Program.cs
Server 대체 파일을 (index.html
)로 app.MapFallbackToFile("index.html");
설정하는 줄 바로 앞에 배치하여 번들 파일에 대한 요청에 응답합니다(예: 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);
});
콘텐츠 형식은 빌드 작업에서 이전에 정의한 형식과 일치합니다. 엔드포인트는 브라우저에서 허용하는 콘텐츠 인코딩을 확인하고 최적의 파일인 Brotli(.br
) 또는 Gzip(.gz
)을 제공합니다.
ASP.NET Core