Blazor Server托管式JavaScript因认证CORS策略导致连接超时崩溃问题求助
这问题确实挺闹心的,我来帮你捋捋核心原因和可行的解决思路:
问题根源拆解
你遇到的核心矛盾点在于:
明明把
app.MapStaticAssets()放在了认证/授权中间件之前,按道理静态资源应该是公开可访问的,但RCL里的托管.razor.js文件却被认证中间件拦截,重定向到Azure AD/B2C登录页,触发了CORS报错。
结合你提到的“清除Cookie后直接访问JS文件也会被重定向”这个测试结果,基本可以确定:Blazor的托管JS文件虽然会被作为静态资产发布,但当你给整个Razor组件路由加上.RequireAuthorization()时,Blazor对这些JS文件的动态导入请求,并没有走普通的静态文件中间件逻辑,而是继承了组件的授权要求,导致请求被拦截。
Blazor重连时会重新初始化组件,这时候触发的JS动态导入请求,因为还没完成认证续期,就被当成了未授权请求,直接重定向到登录页,而登录页域名和你的站点不一致,自然就触发了CORS限制。
可行的解决办法
1. 显式给托管JS文件路径添加匿名访问规则
既然自动的静态资源规则没生效,我们手动给这些JS文件的路径开“绿灯”。在Program.cs中,UseAuthorization()之后、MapRazorComponents()之前,添加这段代码:
// 替换{你的RCL名称}为实际的RCL包名 app.MapWhen(context => context.Request.Path.StartsWithSegments("/_content/{你的RCL名称}") && context.Request.Path.Value.EndsWith(".razor.js"), subApp => subApp.AllowAnonymous());
这段代码会匹配所有来自RCL的托管JS文件请求,强制允许匿名访问,这样即使是Blazor重连时的未授权状态请求,也能正常加载JS文件,不会被重定向。
2. 改用全局引用托管JS文件,避免动态导入
如果上面的方案还是有问题,你可以绕过动态导入的逻辑:
在主应用的_Host.cshtml里,直接添加对该JS文件的全局引用:
<script src="_content/{你的RCL名称}/Components/MyComponent.razor.js"></script>
这样JS文件会在页面首次加载时就被加载完成,Blazor重连时就不会再触发动态导入请求,从根源上避免了这个问题。
3. 检查OIDC配置的路径规则
偶尔也会出现Azure AD/B2C的OIDC配置不小心覆盖了静态资源路径的情况,你可以检查下OIDC配置中的CallbackPath、SignedOutCallbackPath等参数,确保它们没有和/_content/开头的静态资源路径冲突。
补充说明
文档里只提到Blazor会托管JS文件到静态资产,但确实没说明当组件路由全局授权时,动态导入JS的请求会被授权规则影响。手动排除路径是最直接的解决方案,毕竟这些JS文件本身就是无需保护的静态资源。
内容来源于stack exchange

