注意
此版本不是本文的最新版本。 有关当前版本,请参阅.NET 9 版本的本文。
警告
此版本的 ASP.NET Core 不再受支持。 有关详细信息,请参阅 .NET 和 .NET Core 支持策略。 有关当前版本,请参阅.NET 9 版本的本文。
本文介绍 Blazor 应用启动配置。
有关用于服务器端开发的 ASP.NET Core 应用配置的一般指南,请参阅 ASP.NET Core 中的配置。
启动过程和配置
Blazor 启动过程可以通过 Blazor 脚本 (blazor.*.js
) 自动异步完成,其中 *
占位符为:
-
web
的 Blazor Web App - 适用于
server
应用的 Blazor Server - 适用于
webassembly
应用的 Blazor WebAssembly
Blazor 启动过程可以通过 Blazor 脚本 (blazor.*.js
) 自动异步完成,其中 *
占位符为:
- 适用于
server
应用的 Blazor Server - 适用于
webassembly
应用的 Blazor WebAssembly
有关脚本的位置,请参阅 ASP.NET Core Blazor 项目结构。
手动启动 Blazor 的步骤:
Blazor Web App:
- 将
autostart="false"
属性和值添加到 Blazor<script>
标记中。 - 将调用
Blazor.start()
的脚本放置在 Blazor<script>
标记之后并放在结束的</body>
标记内。 - 将静态服务器端呈现(静态 SSR)选项置于
ssr
属性中。 - 将服务器端 Blazor-SignalR 线路选项置于
circuit
属性中。 - 将客户端 WebAssembly 选项置于
webAssembly
属性中。
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
...
Blazor.start({
ssr: {
...
},
circuit: {
...
},
webAssembly: {
...
}
});
...
</script>
独立 Blazor WebAssembly 和 Blazor Server:
- 将
autostart="false"
属性和值添加到 Blazor<script>
标记中。 - 将调用
Blazor.start()
的脚本放置在 Blazor<script>
标记之后并放在结束的</body>
标记内。 - 可以在
Blazor.start()
参数中提供其他选项。
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
...
Blazor.start({
...
});
...
</script>
在前面的示例中,{BLAZOR SCRIPT}
占位符是 Blazor 脚本路径和文件名。 有关脚本的位置,请参阅 ASP.NET Core Blazor 项目结构。
JavaScript 初始值设定项
JavaScript (JS) 初始值设定项在 Blazor 应用加载之前和之后执行逻辑。 JS 初始化器在以下场景中很有用:
- 自定义 Blazor 应用的加载方式。
- 在 Blazor 启动之前初始化库。
- 配置 Blazor 设置。
JS 初始化器会在构建过程中被检测到并自动导入。 使用 JS 初始值设定项通常无需在使用 时Razor。
若要定义 JS 初始值设定项,请向项目添加名为 JS 的 {NAME}.lib.module.js
模块,其中 {NAME}
占位符是程序集名称、库名称或包标识符。 将文件放在项目的 Web 根目录中,通常为 wwwroot
文件夹。
对于 Blazor Web App:
-
beforeWebStart(options)
:在 Blazor Web App 启动之前调用。 例如,beforeWebStart
用于自定义加载过程、日志记录级别和其他选项。 接收 Blazor Web 选项 (options
)。 -
afterWebStarted(blazor)
:在所有beforeWebStart
承诺解决后调用。 例如,afterWebStarted
可用于注册 Blazor 事件侦听器和自定义事件类型。 Blazor 实例作为参数 (afterWebStarted
) 传递给blazor
。 -
beforeServerStart(options, extensions)
:在启动第一个服务器运行时之前调用。 接收 SignalR 路线启动选项 (options
) 以及在发布期间添加的任何扩展 (extensions
)。 -
afterServerStarted(blazor)
:在启动第一个交互式服务器运行时之后调用。 -
beforeWebAssemblyStart(options, extensions)
:在启动交互式 WebAssembly 运行时之前调用。 接收 Blazor 选项 (options
) 以及在发布期间添加的任何扩展 (extensions
)。 例如,选项可以指定使用自定义启动资源加载程序。 -
afterWebAssemblyStarted(blazor)
:在启动交互式 WebAssembly 运行时之后调用。
注意
在 JS 中,默认情况下不会调用旧的 beforeStart
初始值设定项(afterStarted
、Blazor Web App)。 可使用 enableClassicInitializers
选项启用旧版初始值设定项来运行。 但是,旧版初始化器的执行是不可预测的。
<script>
Blazor.start({ enableClassicInitializers: true });
</script>
由于 .NET 8 和 9 (dotnet/aspnetcore
#54049) 中的框架 bug,必须在调用 Blazor 或 beforeWebAssemblyStart(options, extensions)
时手动启动afterWebAssemblyStarted(blazor)
脚本。 如果服务器应用尚未使用 WebAssembly (Blazor) 配置手动启动 webAssembly: {...}
,请在服务器项目中使用以下内容更新 App
组件。
在 Components/App.razor
中,删除现有 Blazor<script>
标记:
- <script src="_framework/blazor.web.js"></script>
将 <script>
标记替换为以下标记,这些标记使用 WebAssembly (Blazor) 配置手动启动 webAssembly: {...}
:
<script src="_framework/blazor.web.js" autostart="false"></script>
<script>
Blazor.start({
webAssembly: {}
});
</script>
对于 Blazor Server、Blazor WebAssembly 和 Blazor Hybrid 应用:
-
beforeStart(options, extensions)
:在 Blazor 启动之前调用。 例如,beforeStart
用于自定义加载过程、日志记录级别以及其他特定于托管模型的选项。- 客户端
beforeStart
接收 Blazor 选项 (options
) 以及在发布期间添加的任何扩展 (extensions
)。 例如,选项可以指定使用自定义启动资源加载程序。 - 服务器端
beforeStart
接收 SignalR 电路启动选项 (options
)。 - 在
BlazorWebView
中,不会传递任何选项。
- 客户端
-
afterStarted(blazor)
:在 Blazor 准备好从 JS 接收调用后调用。 例如,afterStarted
用于通过进行 JS 互操作调用并注册自定义元素来初始化库。 Blazor 实例作为参数 (afterStarted
) 传递给blazor
。
新增 .NET WebAssembly 运行时调用功能:
onRuntimeConfigLoaded(config)
:在下载启动配置时调用。 允许应用在运行时启动前(参数是来自MonoConfig
的dotnet.d.ts
)修改参数(配置):export function onRuntimeConfigLoaded(config) { // Sample: Enable startup diagnostic logging when the URL contains // parameter debug=1 const params = new URLSearchParams(___location.search); if (params.get("debug") == "1") { config.diagnosticTracing = true; } }
onRuntimeReady({ getAssemblyExports, getConfig })
:在 .NET WebAssembly 运行时启动后调用(参数是来自RuntimeAPI
的dotnet.d.ts
):export function onRuntimeReady({ getAssemblyExports, getConfig }) { // Sample: After the runtime starts, but before Main method is called, // call [JSExport]ed method. const config = getConfig(); const exports = await getAssemblyExports(config.mainAssemblyName); exports.Sample.Greet(); }
这两个回调都可以返回一个 Promise
,并会在启动继续之前等待该承诺。
对于文件名:
- 如果 JS 初始值设定项用作项目中的静态资产,请使用格式
{ASSEMBLY NAME}.lib.module.js
,其中{ASSEMBLY NAME}
占位符是应用的程序集名称。 例如,对于程序集名称为BlazorSample.lib.module.js
的项目,将文件命名为BlazorSample
。 将文件放在应用的wwwroot
文件夹中。 - 如果 JS 初始值设定项是从 RCL 使用的,请使用格式
{LIBRARY NAME/PACKAGE ID}.lib.module.js
,其中{LIBRARY NAME/PACKAGE ID}
占位符是项目的库名称或包标识符。 例如,对于包标识符为RazorClassLibrary1.lib.module.js
的 RCL,将文件命名为RazorClassLibrary1
。 将文件放在库的wwwroot
文件夹中。
对于 Blazor Web App:
下面的示例展示了通过将脚本追加到 JS 和 Blazor Web App 中的 <head>
,在 beforeWebStart
启动之前和之后加载自定义脚本的 afterWebStarted
初始值设定项:
export function beforeWebStart() {
var customScript = document.createElement('script');
customScript.setAttribute('src', 'beforeStartScripts.js');
document.head.appendChild(customScript);
}
export function afterWebStarted() {
var customScript = document.createElement('script');
customScript.setAttribute('src', 'afterStartedScripts.js');
document.head.appendChild(customScript);
}
前面的 beforeWebStart
示例仅保证自定义脚本在 Blazor 启动之前加载。 它不保证脚本中等待的承诺在 Blazor 启动之前完成执行。
对于 Blazor Server、Blazor WebAssembly 和 Blazor Hybrid 应用:
下面的示例展示了通过将脚本追加到 JS 和 Blazor 中的 <head>
,在 beforeStart
启动之前和之后加载自定义脚本的 afterStarted
初始值设定项:
export function beforeStart(options, extensions) {
var customScript = document.createElement('script');
customScript.setAttribute('src', 'beforeStartScripts.js');
document.head.appendChild(customScript);
}
export function afterStarted(blazor) {
var customScript = document.createElement('script');
customScript.setAttribute('src', 'afterStartedScripts.js');
document.head.appendChild(customScript);
}
前面的 beforeStart
示例仅保证自定义脚本在 Blazor 启动之前加载。 它不保证脚本中等待的承诺在 Blazor 启动之前完成执行。
注意
MVC 和 Razor 页面应用程序不会自动加载 JS 初始化程序。 但是,开发人员代码可以包含一个脚本,用于提取应用的清单并触发 JS 初始值设定项的加载。
有关 JS 初始化表达式的示例,请参阅以下资源:
- Blazor Web App 加载指示器 (无需预渲染的全局交互式 WebAssembly 渲染示例)
- 使用静态服务器端呈现(静态 SSR)的 ASP.NET Core Blazor JavaScript
-
在 JavaScript 应用和 SPA 框架中使用 Razor 组件(
quoteContainer2
示例) - ASP.NET Core Blazor 事件处理(自定义剪贴板粘贴事件示例)
- 为 ASP.NET Core Blazor Web App 中的 TOTP 验证器应用启用 QR 码生成
-
ASP.NET Core GitHub 存储库中的基本测试应用 (
BasicTestApp.lib.module.js
)
注意
指向 .NET 参考源的文档链接通常会加载存储库的默认分支,该分支表示针对下一个 .NET 版本的当前开发。 若要为特定版本选择标记,请使用“切换分支或标记”下拉列表。 有关详细信息,请参阅如何选择 ASP.NET Core 源代码的版本标记 (dotnet/AspNetCore.Docs #26205)。
确保按特定顺序加载库
按照应加载的顺序将自定义脚本追加到 <head>
和 beforeStart
中的 afterStarted
。
以下示例在 script1.js
之前加载 script2.js
,在 script3.js
之前加载 script4.js
:
export function beforeStart(options, extensions) {
var customScript1 = document.createElement('script');
customScript1.setAttribute('src', 'script1.js');
document.head.appendChild(customScript1);
var customScript2 = document.createElement('script');
customScript2.setAttribute('src', 'script2.js');
document.head.appendChild(customScript2);
}
export function afterStarted(blazor) {
var customScript1 = document.createElement('script');
customScript1.setAttribute('src', 'script3.js');
document.head.appendChild(customScript1);
var customScript2 = document.createElement('script');
customScript2.setAttribute('src', 'script4.js');
document.head.appendChild(customScript2);
}
导入其他模块
使用 import
初始值设定项文件中的顶级 JS 语句导入其他模块。
additionalModule.js
:
export function logMessage() {
console.log('logMessage is logging');
}
在 JS 初始值设定项文件 (.lib.module.js
) 中:
import { logMessage } from "/additionalModule.js";
export function beforeStart(options, extensions) {
...
logMessage();
}
导入映射
文档准备就绪时初始化 Blazor
当文档准备就绪时,以下示例将启动 Blazor:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
Blazor.start();
});
</script>
在前面的示例中,{BLAZOR SCRIPT}
占位符是 Blazor 脚本路径和文件名。 有关脚本的位置,请参阅 ASP.NET Core Blazor 项目结构。
链接到由手动启动生成的 Promise
若要执行其他任务(如 JS 互操作初始化),请使用 then
链接到 Promise
(由手动 Blazor 应用启动生成):
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start().then(function () {
...
});
</script>
在前面的示例中,{BLAZOR SCRIPT}
占位符是 Blazor 脚本路径和文件名。 有关脚本的位置,请参阅 ASP.NET Core Blazor 项目结构。
注意
若要在 Blazor 启动后使库自动执行其他任务,请使用 JavaScript 初始值设定项。 使用 JS 初始值设定项不需要库的使用者将 JS 调用链接到 Blazor 的手动启动。
加载客户端启动资源
当应用程序在浏览器中加载时,该应用程序将从服务器下载启动资源:
- 用于启动应用程序的 JavaScript 代码
- .NET 运行时和程序集
- 本地化数据
自定义如何使用 loadBootResource
API 加载这些启动资源。
loadBootResource
函数会重写内置启动资源加载机制。 在以下场景中使用 loadBootResource
:
- 从 CDN 加载静态资源,例如时区数据或
dotnet.wasm
。 - 使用 HTTP 请求加载压缩的程序集,并将其解压缩到不支持从服务器提取压缩内容的主机的客户端上。
- 将每个
fetch
请求重定向到新名称,从而为资源提供别名。
注意
外部源必须返回浏览器所需的跨源资源共享 (CORS) 标头以允许跨源资源加载。 CDN 通常会提供所需的标头。
loadBootResource
参数如下表所示。
参数 | 描述 |
---|---|
type |
资源类型。 允许的类型包括:assembly 、pdb 、dotnetjs 、dotnetwasm 和 timezonedata 。 你只需指定自定义行为的类型。 框架会根据默认的加载行为加载未指定到 loadBootResource 的类型。
dotnetjs 启动资源 (dotnet.*.js ) 必须返回表示默认加载行为的 null 或表示 dotnetjs 启动资源的源的 URI。 |
name |
资源的名称。 |
defaultUri |
资源的相对或绝对 URI。 |
integrity |
表示响应中的预期内容的完整性字符串。 |
loadBootResource
函数可以返回 URI 字符串以替代加载进程。 在以下示例中,来自 bin/Release/{TARGET FRAMEWORK}/wwwroot/_framework
的以下文件从 CDN 的 https://cdn.example.com/blazorwebassembly/{VERSION}/
提供:
dotnet.*.js
dotnet.wasm
- 时区数据
{TARGET FRAMEWORK}
占位符是目标框架名字对象(例如 net7.0
)。
{VERSION}
占位符是共享框架版本(例如 7.0.0
)。
Blazor Web App:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
webAssembly: {
loadBootResource: function (type, name, defaultUri, integrity) {
console.log(`Loading: '${type}', '${name}', '${defaultUri}', '${integrity}'`);
switch (type) {
case 'dotnetjs':
case 'dotnetwasm':
case 'timezonedata':
return `https://cdn.example.com/blazorwebassembly/{VERSION}/${name}`;
}
}
}
});
</script>
独立 Blazor WebAssembly:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
loadBootResource: function (type, name, defaultUri, integrity) {
console.log(`Loading: '${type}', '${name}', '${defaultUri}', '${integrity}'`);
switch (type) {
case 'dotnetjs':
case 'dotnetwasm':
case 'timezonedata':
return `https://cdn.example.com/blazorwebassembly/{VERSION}/${name}`;
}
}
});
</script>
在前面的示例中,{BLAZOR SCRIPT}
占位符是 Blazor 脚本路径和文件名。 有关脚本的位置,请参阅 ASP.NET Core Blazor 项目结构。
除了为启动资源自定义 URL 外,该 loadBootResource
函数还可以直接调用 fetch
并返回结果。 以下示例将一个自定义 HTTP 标头添加到出站请求。 若要保持默认的完整性检查行为,请传递 integrity
参数。
Blazor Web App:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
webAssembly: {
loadBootResource: function (type, name, defaultUri, integrity) {
if (type == 'dotnetjs') {
return null;
} else {
return fetch(defaultUri, {
cache: 'no-cache',
integrity: integrity,
headers: { 'Custom-Header': 'Custom Value' }
});
}
}
}
});
</script>
独立 Blazor WebAssembly:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
loadBootResource: function (type, name, defaultUri, integrity) {
if (type == 'dotnetjs') {
return null;
} else {
return fetch(defaultUri, {
cache: 'no-cache',
integrity: integrity,
headers: { 'Custom-Header': 'Custom Value' }
});
}
}
});
</script>
在前面的示例中,{BLAZOR SCRIPT}
占位符是 Blazor 脚本路径和文件名。 有关脚本的位置,请参阅 ASP.NET Core Blazor 项目结构。
当 loadBootResource
函数返回 null
时,Blazor 采用资源的默认加载行为。 例如,上述代码为 null
启动资源 (dotnetjs
) 返回 dotnet.*.js
,因为 dotnetjs
启动资源必须返回表示默认加载行为的 null
或表示 dotnetjs
启动资源的源的 URI。
loadBootResource
函数还可以返回 Response
promise。 有关示例,请参阅托管和部署 ASP.NET Core Blazor WebAssembly。
有关详细信息,请参阅 ASP.NET Core Blazor WebAssembly .NET 捆绑包缓存和完整性检查失败。
控制 C# 代码中的标头
使用下列方法控制 C# 代码中启动时的标头。
在以下示例中,通过 CSP 标头将内容安全策略 (CSP) 应用于应用。
{POLICY STRING}
占位符是 CSP 策略字符串。 有关 CSP 的详细信息,请参阅为 ASP.NET Core Blazor 强制实施内容安全策略。
注意
响应启动后,无法设置标头。 本部分中的方法仅在响应启动前设置标头,因此此处介绍的方法是安全的。 有关详细信息,请参阅 ASP.NET Core Blazor 应用中IHttpContextAccessor/HttpContext。
服务器端和预呈现的客户端情景
使用 ASP.NET Core 中间件来控制标头集合。
在 Program
文件中:
在 Startup.Configure
的 Startup.cs
中:
app.Use(async (context, next) =>
{
context.Response.Headers.Append("Content-Security-Policy", "{POLICY STRING}");
await next();
});
前面的示例使用内联中间件,但你也可以创建自定义中间件类,并使用 Program
文件中的扩展方法调用中间件。 有关详细信息,请参阅编写自定义 ASP.NET Core 中间件。
无需预呈现的客户端开发
将 StaticFileOptions 传递给 MapFallbackToFile,以指定 OnPrepareResponse 阶段的响应标头。
在服务器端 Program
文件中:
在 Startup.Configure
的 Startup.cs
中:
var staticFileOptions = new StaticFileOptions
{
OnPrepareResponse = context =>
{
context.Context.Response.Headers.Append("Content-Security-Policy",
"{POLICY STRING}");
}
};
...
app.MapFallbackToFile("index.html", staticFileOptions);
客户端端加载指示器
加载指示器显示应用正在正常加载,并且用户应等待加载完成。
Blazor Web App 加载指示器
应用中使用的 Blazor WebAssembly 加载指示器不在从 Blazor Web App 项目模板创建的应用中。 通常,加载指示器并不适合交互式 WebAssembly 组件,因为 Blazor Web App 在服务器上预渲染客户端组件,可以实现快速的初始加载时间。 对于混合呈现模式的情况,框架或开发人员代码还必须注意避免以下问题:
- 在同一呈现页面上显示多个加载指示器。
- 在加载 .NET WebAssembly 运行时时无意中丢弃了预呈现的内容。
.NET 的未来版本可能提供基于框架的加载指示器。 与此同时,您可以将自定义加载指示器添加到Blazor Web App。
具有预呈现的每个分量交互式 WebAssembly 呈现
此方案适用于逐个组件的交互式 WebAssembly 渲染(@rendermode InteractiveWebAssembly
应用于单个组件)。
在ContentLoading
应用的Layout
文件夹中创建.Client
组件,该组件调用OperatingSystem.IsBrowser:
-
false
时,显示加载指示器。 - 为
true
时,呈现请求的组件的内容。
要为指示器加载 CSS 样式,请将样式添加到附带 <head>
组件的 HeadContent 内容中。 有关详细信息,请参阅在 ASP.NET Core Blazor 应用中控制页面头部内容。
Layout/ContentLoading.razor
:
@if (!RendererInfo.IsInteractive)
{
<!-- OPTIONAL ...
<HeadContent>
<style>
...
</style>
</HeadContent>
-->
<progress id="loadingIndicator" aria-label="Content loading…"></progress>
}
else
{
@ChildContent
}
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
@if (!OperatingSystem.IsBrowser())
{
<!-- OPTIONAL ...
<HeadContent>
<style>
...
</style>
</HeadContent>
-->
<progress id="loadingIndicator" aria-label="Content loading…"></progress>
}
else
{
@ChildContent
}
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
如果项目中还没有 Layout
文件夹 .Client
,请将文件夹的 Layout
命名空间添加到 _Imports.razor
文件中。 在以下示例中,项目的命名空间为 BlazorSample.Client
:
@using BlazorSample.Client.Layout
在采用交互式 WebAssembly 呈现的组件中,使用 Razor 组件包装组件的 ContentLoading
标记。 下面的示例使用从 Counter
项目模板创建应用的 Blazor Web App 组件演示了该方法。
Pages/Counter.razor
:
@page "/counter"
@rendermode InteractiveWebAssembly
<PageTitle>Counter</PageTitle>
<ContentLoading>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
</ContentLoading>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}
具有预呈现的全局交互式 WebAssembly 呈现
此方案适用于具有预呈现的全局交互式 WebAssembly 呈现(在 @rendermode="InteractiveWebAssembly"
分量的 HeadOutlet
和 Routes
分量上的 App
)。
在ContentLoading
应用的Layout
文件夹中创建.Client
组件,该组件调用RendererInfo.IsInteractive:
-
false
时,显示加载指示器。 - 为
true
时,呈现请求的组件的内容。
要为指示器加载 CSS 样式,请将样式添加到附带 <head>
组件的 HeadContent 内容中。 有关详细信息,请参阅在 ASP.NET Core Blazor 应用中控制页面头部内容。
Layout/ContentLoading.razor
:
@if (!RendererInfo.IsInteractive)
{
<!-- OPTIONAL ...
<HeadContent>
<style>
...
</style>
</HeadContent>
-->
<progress id="loadingIndicator" aria-label="Content loading…"></progress>
}
else
{
@ChildContent
}
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
@if (!OperatingSystem.IsBrowser())
{
<!-- OPTIONAL ...
<HeadContent>
<style>
...
</style>
</HeadContent>
-->
<progress id="loadingIndicator" aria-label="Content loading…"></progress>
}
else
{
@ChildContent
}
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
如果项目中还没有 Layout
文件夹 .Client
,请将文件夹的 Layout
命名空间添加到 _Imports.razor
文件中。 在以下示例中,项目的命名空间为 BlazorSample.Client
:
@using BlazorSample.Client.Layout
在MainLayout
项目的Layout/MainLayout.razor
组件(.Client
)中,用Body组件包装@Body
属性(ContentLoading
):
在 Layout/MainLayout.razor
中:
+ <ContentLoading>
@Body
+ </ContentLoading>
不具有预呈现的全局交互式 WebAssembly 呈现
此方案适用于不具有预呈现的全局交互式 WebAssembly 呈现(在 @rendermode="new InteractiveWebAssemblyRenderMode(prerender: false)"
分量的 HeadOutlet
和 Routes
分量上的 App
)。
将 JavaScript 初始值设定项 添加到应用。 在以下 JavaScript 模块文件名示例中, {ASSEMBLY NAME}
占位符是服务器项目的程序集名称(例如, BlazorSample
)。
wwwroot
模块所在的文件夹是wwwroot
服务器端项目中的文件夹,而不是.Client
项目。
以下示例使用一个 progress
指示器,它并不指示实际的进度,仅为将 客户端启动资源传送到客户端提供一个通用的开发方法。如果您想让进度指示器显示加载应用启动资源的实际进度,可以在此基础上进行进一步开发。
wwwroot/{ASSEMBLY NAME}.lib.module.js
:
export function beforeWebStart(options) {
var progress = document.createElement("progress");
progress.id = 'loadingIndicator';
progress.ariaLabel = 'Blazor loading…';
progress.style = 'position:absolute;top:50%;left:50%;margin-right:-50%;' +
'transform:translate(-50%,-50%);';
document.body.appendChild(progress);
}
export function afterWebAssemblyStarted(blazor) {
var progress = document.getElementById('loadingIndicator');
progress.remove();
}
由于 .NET 8 和 9(dotnet/aspnetcore
#54049)中的框架缺陷,必须手动启动 Blazor 脚本。 如果服务器应用尚未使用 WebAssembly (Blazor) 配置手动启动 webAssembly: {...}
,请在服务器项目中使用以下内容更新 App
组件。
在 Components/App.razor
中,删除现有 Blazor<script>
标记:
- <script src="_framework/blazor.web.js"></script>
将 <script>
标记替换为以下标记,这些标记使用 WebAssembly (Blazor) 配置手动启动 webAssembly: {...}
:
<script src="_framework/blazor.web.js" autostart="false"></script>
<script>
Blazor.start({
webAssembly: {}
});
</script>
如果注意到加载指示器被移除与第一页渲染之间有短暂的延迟,可以通过在 OnAfterRenderAsync
或 分量的 MainLayout
中调用指示器移除来确保在呈现后删除指示器。 有关详细信息和代码示例,请参阅记录一种与不具有预呈现的全局交互式 WebAssembly 一起使用的加载指示器的方法 (dotnet/AspNetCore.Docs
#35111)。
Blazor WebAssembly 应用加载进度
项目模板包含可缩放矢量图形 (SVG) 和显示应用加载进度的文本指示器。
进度指示器是使用 Blazor 提供的两个 CSS 自定义属性(变量)通过 HTML 和 CSS 实现的:
-
--blazor-load-percentage
:加载的应用文件的百分比。 -
--blazor-load-percentage-text
:加载的应用文件的百分比,四舍五入为最接近的整数。
使用上述 CSS 变量可以创建与应用样式匹配的自定义进度指示器。
在下面的示例中:
-
resourcesLoaded
是应用启动期间加载的资源的瞬时计数。 -
totalResources
是要加载的资源总数。
const percentage = resourcesLoaded / totalResources * 100;
document.documentElement.style.setProperty(
'--blazor-load-percentage', `${percentage}%`);
document.documentElement.style.setProperty(
'--blazor-load-percentage-text', `"${Math.floor(percentage)}%"`);
默认舍入进度指示器在 wwwroot/index.html
文件中的 HTML 中实现:
<div id="app">
<svg class="loading-progress">
<circle r="40%" cx="50%" cy="50%" />
<circle r="40%" cx="50%" cy="50%" />
</svg>
<div class="loading-progress-text"></div>
</div>
若要查看默认进度指示器的 项目模板标记和样式,请参阅 ASP.NET Core 参考源:
注意
指向 .NET 参考源的文档链接通常会加载存储库的默认分支,该分支表示针对下一个 .NET 版本的当前开发。 若要为特定版本选择标记,请使用“切换分支或标记”下拉列表。 有关详细信息,请参阅如何选择 ASP.NET Core 源代码的版本标记 (dotnet/AspNetCore.Docs #26205)。
以下示例演示了如何实现线性进度指示器,而不是使用默认的舍入进度指示器。
向 wwwroot/css/app.css
添加以下样式:
.linear-progress {
background: silver;
width: 50vw;
margin: 20% auto;
height: 1rem;
border-radius: 10rem;
overflow: hidden;
position: relative;
}
.linear-progress:after {
content: '';
position: absolute;
inset: 0;
background: blue;
scale: var(--blazor-load-percentage, 0%) 100%;
transform-origin: left top;
transition: scale ease-out 0.5s;
}
CSS 变量 (var(...)
) 用于将 --blazor-load-percentage
的值传递给蓝色伪元素的 scale
属性,该属性指示应用文件的加载进度。 当应用加载时,--blazor-load-percentage
会自动更新,这会动态更改进度指示器的可视表示形式。
在 wwwroot/index.html
中,删除 <div id="app">...</div>
中的默认 SVG 舍入指示器,并将其替换为以下标记:
<div class="linear-progress"></div>
配置 .NET WebAssembly 运行时
在高级编程方案中,会将 configureRuntime
函数与 dotnet
运行时主机生成器配合使用来配置 .NET WebAssembly 运行时。 例如,dotnet.withEnvironmentVariable
设置一个环境变量:
- 配置 .NET WebAssembly 运行时。
- 更改 C 库的行为。
注意
dotnet/runtime
GitHub 存储库中有一个文档请求正在等待处理,以获取有关配置 .NET WebAssembly 运行时或影响 C 库行为的环境变量的详细信息。 尽管文档请求处于挂起状态,但请求中提供了指向其他资源的详细信息和交叉链接有关 .NET WASM 运行时环境变量的文档的问题/请求 (dotnet/runtime
#98225)。
configureRuntime
函数还可用于启用与浏览器探查器的集成。
对于以下示例中用于设置环境变量的占位符:
-
{BLAZOR SCRIPT}
占位符是 Blazor 脚本路径和文件名。 有关脚本的位置,请参阅 ASP.NET Core Blazor 项目结构。 -
{NAME}
占位符是环境变量的名称。 -
{VALUE}
占位符是环境变量的值。
Blazor Web App:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
webAssembly: {
configureRuntime: dotnet => {
dotnet.withEnvironmentVariable("{NAME}", "{VALUE}");
}
}
});
</script>
独立 Blazor WebAssembly:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
configureRuntime: dotnet => {
dotnet.withEnvironmentVariable("{NAME}", "{VALUE}");
}
});
</script>
注意
可使用 .NET WebAssembly 运行时 API (Blazor.runtime
) 访问 .NET 运行时实例。 例如,可以使用 Blazor.runtime.runtimeBuildInfo.buildConfiguration
获取应用的生成配置。
有关 .NET WebAssembly 运行时配置的详细信息,请参阅 dotnet.d.ts
GitHub 存储库中的运行时 TypeScript 定义文件 (dotnet/runtime
)。
注意
指向 .NET 参考源的文档链接通常会加载存储库的默认分支,该分支表示针对下一个 .NET 版本的当前开发。 若要为特定版本选择标记,请使用“切换分支或标记”下拉列表。 有关详细信息,请参阅如何选择 ASP.NET Core 源代码的版本标记 (dotnet/AspNetCore.Docs #26205)。
禁用增强型导航和表单处理
本部分适用于 Blazor Web App。
若要禁用增强型导航和表单处理,请将 disableDomPreservation
的 true
设置为 Blazor.start
:
<script src="{BLAZOR SCRIPT}" autostart="false"></script>
<script>
Blazor.start({
ssr: { disableDomPreservation: true }
});
</script>
在前面的示例中,{BLAZOR SCRIPT}
占位符是 Blazor 脚本路径和文件名。 有关脚本的位置,请参阅 ASP.NET Core Blazor 项目结构。