解决Blazor WebAssembly跨域访问后台服务问题

Posted JimCarter

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决Blazor WebAssembly跨域访问后台服务问题相关的知识,希望对你有一定的参考价值。

1. 前言

因为Blazor Server Side用的是SignalR,不存在跨域问题。所以这里我们针对的是Blazor WebAssembly。浏览器跨域问题是啥不用做过多解释,因为当blazor请求其它服务提供的接口时,使用的HttpClient类本质调用的还是浏览器的fetch函数,所以依然处于浏览器的管辖范围内,还是有跨域问题。

2. 解决

熟悉react开发的同学应该知道Node作为react的Host,可以通过配置一个类似proxy.js的文件代为请求具体的服务接口。

所以这个问题的解决方法其实也很简单:通过服务端代理转发请求

但是解决问题的一个前提是,得知道你Blazor的Host是啥?
在这里插入图片描述
(这里我创建Blazor项目的时候选择了使用ASP.NET Core作为Host)

所以如果你的项目仅仅是一个webassembly的项目,没有具体的Host,还是尽量跟后台服务部署到同一个域名端口下吧,否则解决起来还是比较麻烦的。

2.1 配置代理

在Server项目中安装以下nuget包:

  • Microsoft.AspNetCore.Proxy:代理
  • Microsoft.AspNetCore.Rewrite:url重定向和重写,不需要的话可以不装,我这里是因为需要在每次请求的url后面跟上一些参数。

然后在startup.cs中进行配置。因为我这边只需要在本地用VS开发调试的时候进行代理,发布生产的时候是在网关域名下面,不存在跨域访问的问题,所以我这里将配置项写在了if (env.IsDevelopment())里。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IOptions<ProxyConfig> proxyConfig)
{
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseWebAssemblyDebugging();

                //URL重写,增加额外查询参数
                var opt = new RewriteOptions();
                string trimPrefix = string.Empty;
                proxyConfig.Value.ServicePrefixs.ForEach(prefix =>
                {
                    trimPrefix = prefix.Trim('/');
                    opt.AddRewrite($"{trimPrefix}/(.*)", $"{trimPrefix}/$1{proxyConfig.Value.UserInfo}", true);
                });
                
                app.UseRewriter(opt);

                //代理
                app.MapWhen(context => proxyConfig.Value.ServicePrefixs.Exists(prefix => context.Request.Path.StartsWithSegments(prefix)), builder =>
                     {
                         builder.RunProxy(new ProxyOptions
                         {
                             Host = proxyConfig.Value.Host
                      	});
                     });
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }

            //...
        }

ProxyConfig是一个配置项,配置了要代理的域名以及哪些路径需要进行代理:

    public class ProxyConfig
    {
        public const string SectionName = "Proxy";
        //用户信息
        public string UserInfo { get; set; }
        public string Host { get; set; }
        public List<string> ServicePrefixs { get; set; }
    }

appsettings.json如下:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "Proxy": {
    "UserInfo": "?devMode=True&a=12284&b=585",
    "Host": "www.example.com",
    "ServicePrefixs": [
      "/service1",
      "/service2",
      "/service3"]
  }
}

2.2 完成

开始顺利的Debug吧,跨域不再是问题。

以上是关于解决Blazor WebAssembly跨域访问后台服务问题的主要内容,如果未能解决你的问题,请参考以下文章

解决Blazor WebAssembly跨域访问后台服务问题

无法从 Blazor WebAssembly 应用本地访问 Azure Function Api

Blazor WebAssembly的初次访问慢的优化

Blazor WebAssembly的初次访问慢的优化

如何从 Blazor WebAssembly 中的 Razor 页面访问 body 标签或其他标签?

Blazor WebAssembly - 找不到适合类型“JwtSecurityTokenHandler”的构造函数