URL 重写 Blazor WebAssembly 托管部署的异常
URL Rewrite exceptions for Blazor WebAssembly Hosted deployment
在开发过程中,我在我的 Blazor WebAssembly 应用程序的服务器端使用了 Swagger。始终使用 kestrel 而不是 IIS Express 启动(调试)。
路由按预期工作,我的所有组件都正确路由,如果我手动输入 /swagger,我会进入 swagger 页面。一切顺利。
我们已经在预生产服务器上部署了 IIS,服务器端和 Blazor WebAssembly 应用程序(客户端)按预期工作并且可用,但是,我的 /swagger url 被重写了(我假设)去我的应用程序中的某个地方而不是让它去 Swagger,显然没有任何组件可以响应 /swagger。
我唯一的猜测是,当托管在 IIS 上时,aspnet 核心应用程序负责告诉 IIS 重写什么以及如何重写(类似于可以通过 web.config 为 "Standalone"部署。)
我找不到如何指定例外情况,我一直在关注文档
https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/blazor/webassembly?view=aspnetcore-3.1#iis
知道如何为 /swagger 添加例外吗?
编辑:
事实证明它在 Chrome 中没有问题,只有 Firefox 有不需要的行为。如果我清除缓存或使用隐身模式,则该问题不会在 Firefox 中发生。因此,Firefox 似乎缓存了一些东西并尝试将我的 URL 输入发送到 Blazor Wasm,而不是通过服务器。我将使用开发工具和提琴手进行更多调试,以尝试找出答案。
您的 Startup.Configure
方法中是否首先使用了 UseSwagger?
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
c.SwaggerEndpoint("/swagger/v1/swagger.json", "YourAppName V1")
);
在 Startup.ConfigureServices
中,我最后有 Swagger 代码。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSwaggerGen(c =>
c.SwaggerDoc(
name: "v1",
info: new OpenApiInfo
{
Title = "YourAppName",
Version = "V1",
}));
}
这对我们来说工作得很好。
注意:您必须导航至 https://yourdomain/swagger/index.html
原来这是发布的 service-worker.js 文件的一部分。它在开发中不同于发布的内容(这是有道理的)。
在调试期间,我能够在所有浏览器(Edge、Chrome 和 Firefox)上重现该问题,无论是否处于 Incognito/Private 模式。
一旦服务工作者 运行,它就会处理来自 Blazor WebAssembly 应用程序 cache/index.html 的服务请求。
如果您进入您的 Blazor WebAssembly 客户端 "wwwroot" 文件夹,您将找到一个服务-worker.js 和一个服务-worker.published.js。在服务-worker.published.js中,你会发现一个看起来像这样的函数:
async function onFetch(event) {
let cachedResponse = null;
if (event.request.method === 'GET') {
// For all navigation requests, try to serve index.html from cache
// If you need some URLs to be server-rendered, edit the following check to exclude those URLs
const shouldServeIndexHtml = event.request.mode === 'navigate'
&& !event.request.url.includes('/connect/')
&& !event.request.url.includes('/Identity/');
const request = shouldServeIndexHtml ? 'index.html' : event.request;
const cache = await caches.open(cacheName);
cachedResponse = await cache.match(request);
}
return cachedResponse || fetch(event.request);
}
只需按照代码注释中的说明进行操作即可解决问题。所以我们最终为“/swagger”添加了一个排除项,如下所示:
&& !event.request.url.includes('/swagger')
希望这个 post 对那些想要在 service worker 之外提供服务的人有用,而不仅仅是 Swagger。
在开发过程中,我在我的 Blazor WebAssembly 应用程序的服务器端使用了 Swagger。始终使用 kestrel 而不是 IIS Express 启动(调试)。 路由按预期工作,我的所有组件都正确路由,如果我手动输入 /swagger,我会进入 swagger 页面。一切顺利。
我们已经在预生产服务器上部署了 IIS,服务器端和 Blazor WebAssembly 应用程序(客户端)按预期工作并且可用,但是,我的 /swagger url 被重写了(我假设)去我的应用程序中的某个地方而不是让它去 Swagger,显然没有任何组件可以响应 /swagger。
我唯一的猜测是,当托管在 IIS 上时,aspnet 核心应用程序负责告诉 IIS 重写什么以及如何重写(类似于可以通过 web.config 为 "Standalone"部署。)
我找不到如何指定例外情况,我一直在关注文档 https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/blazor/webassembly?view=aspnetcore-3.1#iis
知道如何为 /swagger 添加例外吗?
编辑:
事实证明它在 Chrome 中没有问题,只有 Firefox 有不需要的行为。如果我清除缓存或使用隐身模式,则该问题不会在 Firefox 中发生。因此,Firefox 似乎缓存了一些东西并尝试将我的 URL 输入发送到 Blazor Wasm,而不是通过服务器。我将使用开发工具和提琴手进行更多调试,以尝试找出答案。
您的 Startup.Configure
方法中是否首先使用了 UseSwagger?
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
c.SwaggerEndpoint("/swagger/v1/swagger.json", "YourAppName V1")
);
在 Startup.ConfigureServices
中,我最后有 Swagger 代码。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddSwaggerGen(c =>
c.SwaggerDoc(
name: "v1",
info: new OpenApiInfo
{
Title = "YourAppName",
Version = "V1",
}));
}
这对我们来说工作得很好。
注意:您必须导航至 https://yourdomain/swagger/index.html
原来这是发布的 service-worker.js 文件的一部分。它在开发中不同于发布的内容(这是有道理的)。
在调试期间,我能够在所有浏览器(Edge、Chrome 和 Firefox)上重现该问题,无论是否处于 Incognito/Private 模式。
一旦服务工作者 运行,它就会处理来自 Blazor WebAssembly 应用程序 cache/index.html 的服务请求。
如果您进入您的 Blazor WebAssembly 客户端 "wwwroot" 文件夹,您将找到一个服务-worker.js 和一个服务-worker.published.js。在服务-worker.published.js中,你会发现一个看起来像这样的函数:
async function onFetch(event) {
let cachedResponse = null;
if (event.request.method === 'GET') {
// For all navigation requests, try to serve index.html from cache
// If you need some URLs to be server-rendered, edit the following check to exclude those URLs
const shouldServeIndexHtml = event.request.mode === 'navigate'
&& !event.request.url.includes('/connect/')
&& !event.request.url.includes('/Identity/');
const request = shouldServeIndexHtml ? 'index.html' : event.request;
const cache = await caches.open(cacheName);
cachedResponse = await cache.match(request);
}
return cachedResponse || fetch(event.request);
}
只需按照代码注释中的说明进行操作即可解决问题。所以我们最终为“/swagger”添加了一个排除项,如下所示:
&& !event.request.url.includes('/swagger')
希望这个 post 对那些想要在 service worker 之外提供服务的人有用,而不仅仅是 Swagger。