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

我想制作一个应用程序,我需要在基域上使用静态页面,在子目录上使用 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 项目上。

有人可以指出我如何实现这一目标的正确方向吗?

提前致谢!

stack overflow Move Blazor WASM to subdirectory (base directory static files)
原文答案

答案:

作者头像

子目录名称需要出现在四个地方。

在您的 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://docs.microsoft.com/en-us/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>

身份功能所需的其他更改:

  • 在 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"
        }
      }
作者头像

我查看了 Daz 的答案,它在调试/运行独立产品时确实解决了问题。但是,我的生产环境是基于 Kubernetes 的,并且我的入口控制器不会将请求路由到正确的位置,例如:

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

  • 将索引文件中的 设置为
  • 在服务器 ConfigureServices 函数中设置 app.UseBlazorFrameworkFiles(new PathString("/app"))
  • 在服务器配置函数、UseEndpoints 选项中设置 endpoints.MapFallbackToFile("/app/{*path:nonfile}", "app/index.html")
  • app 添加到 csproj 文件的客户端的 部分。

除了作为嵌入式文件的单个文件“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 子句,每个文件的列表中都有一个条目。显然,如果您知道应该重定向整个文件夹,这可以简化。

由于在服务器中重写路径对客户端应用程序是不可见的,所以这个简单的更新解决了这个问题。

标记