将 Blazor WASM 移动到子目录 (基础目录静态文件)。

10
我想制作一个应用程序,在基础域上需要静态页面和一个子目录上的Blazor应用程序。
例如:
https://example.com 是我的静态页面所在的地方(如'/features'、'/pricing'或'/faq')
https://example.com/app 是我的Blazor网站所在的地方。
我看到可以通过传递PathString到app.UseBlazorFrameworkFiles,但是这并不起作用(app.UseBlazorFrameworkFiles(new PathString("/app"))。我的Blazor应用程序托管在具有gRPC的.NET 5 WebApi项目上。
有人可以指引我朝着正确的方向实现这个目标吗?
先行致谢!

嗨@BrianParker,是的,我做了。我已经在Client/wwwroot/app/index.html中添加了<base href="/app/" />',其中包含<div id="app">...并加载blazor.webassembly.js`文件。 - Coupz
2个回答

8
子目录名称需要出现在四个位置。
在您的WebAPI项目的Startup.cs中,您需要:
app.UseBlazorFrameworkFiles(new PathString("/app"));

并在端点配置中:

endpoints.MapFallbackToFile("/app/{*path:nonfile}", "app/index.html");

在Wasm应用程序的wwwroot/index.html文件中:
<base href="/app/" />

在Wasm应用程序的CSProj文件中:
<StaticWebAssetBasePath>app</StaticWebAssetBasePath>

文档:https://learn.microsoft.com/zh-cn/aspnet/core/blazor/host-and-deploy/webassembly?view=aspnetcore-5.0#hosted-deployment-with-multiple-blazor-webassembly-apps

这里有一个示例实现:https://github.com/javiercn/BlazorMultipleApps

如果您使用了默认的带有 Identity 的 Wasm 模板,则会发现客户端无法正确加载,因为打包在 microsoft.aspnetcore.components.webassembly.authentication 内的静态资源未被提供。为了解决此问题,请将 index.html 中的 src 更改为绝对路径:

<script src="/_content/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"></script>

为使Identity功能正常运行,需要进行其他更改:

  • 在AppSettings中,将IdentityServer客户端配置文件从"IdentityServerSPA"更改为"SPA"
  • 指定"RedirectUri"和"LogoutUri"以包含新的子目录
      "Clients": {
        "BlazorApp.Client": {
          "Profile": "SPA",
          "RedirectUri": "https://localhost:44357/app/authentication/login-callback",
          "LogoutUri": "https://localhost:44357/app/authentication/logout-callback"
        }
      }

第五步,将 app.UseStaticFiles("/app"); 添加到 startup.cs 中。否则某些静态文件可能会出现404错误。 - Jim
1
如果您想从一个服务器托管多个Wasm应用程序,则可以在https://learn.microsoft.com/en-us/aspnet/core/blazor/host-and-deploy/webassembly?view=aspnetcore-5.0#hosted-deployment-with-multiple-blazor-webassembly-apps中找到详细步骤,该文档还列出了您需要调整路径的所有位置。 - Daz

3

我查看了Daz的回答,它确实可以修复在调试/运行独立产品时出现的问题。然而,我的生产环境基于Kubernetes,我的入口控制器无法将请求路由到正确的位置,例如:

在我的示例中,我已经更改了通常的四个设置:

  • 将index文件中的<base href>设置为<base href="/app/" />
  • 在服务器的ConfigureServices函数中设置app.UseBlazorFrameworkFiles(new PathString("/app"))
  • 在服务器的Configure函数中,使用UseEndpoints选项设置endpoints.MapFallbackToFile("/app/{*path:nonfile}", "app/index.html")
  • 在客户端的csproj文件的<PropertyGroup>部分中添加<StaticWebAssetBasePath>app

除了一个嵌入式文件"Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"之外,一切都正常工作。

由于需要从服务器获取该文件,因此在客户端中调整文件路径是行不通的,因为它不会被我的入口配置正确路由。对于我的应用程序,我添加了一个非常简单的中间件如下:

        // "/{app}/_content/{embedded-library-files}/{file}" requests need to be presented at root
        app.Use(async (context, next) =>
        {
            HttpRequest request = context.Request;
            var path = request.Path;
            if (path.StartsWithSegments(new PathString("/app/_content")))
            {
                if (new string[] {
                    "/Microsoft.AspNetCore.Components.WebAssembly.Authentication/AuthenticationService.js"
                }.Any(s => path.Value.EndsWith(s)))
                {
                    request.Path = path.Value.Substring("/app".Length);
                }
            }

            await next.Invoke();
        });

对于每个文件夹都需要一个if语句,并且每个文件都需要在列表中有条目。如果您知道整个文件夹应该重定向,那么显然可以简化此过程。

由于在服务器上重新编写路径对客户端应用程序不可见,因此这个简单的更新修复了问题。

马克


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接