跨域问题概述

跨域指浏览器不能执行其他网站的脚本,这是由浏览器的同源策略造成的,是浏览器对 JavaScript 施加的安全限制。

造成跨域的原因

  1. 域名相同,端口不同。
  2. 域名相同,协议不同(如一个是 http,一个是 https)。
  3. 访问其他网站时,一个是域名,一个是对应的 IP 地址(例如:http://www.a.com ------ http://192.168.1.1)。
  4. 主域名相同,子域名不同。
  5. 两个完全不相同的域名。

简单来说,只有域名、协议、端口都相同才能通信。
在这里插入图片描述在这里插入图片描述

跨域报错及解决思路

凡是特定的两种报错都属于跨域问题。一般来说,前端解决跨域比较复杂,后端解决相对简单,因此通常由后端解决跨域问题。

以 Net Core 3.x WebApi 框架解决跨域问题

1、WebApi 代码配置

官方方案参考:https://learn.microsoft.com/zh-cn/aspnet/core/security/cors?view=aspnetcore-3.1

  1. 在 Startup.cs 文件的 ConfigureServices 方法中添加跨域配置
    跨域有两种配置方法,一种是允许所有域名,一种是配置部分域名通信,示例代码如下:
public void ConfigureServices(IServiceCollection services)
{
    #region 解决跨域
    //“Cors”表示策略名称,可以随便起;可以添加多条策略。
    //AllowAnyOrigin表示允许任何域;AllowAnyMethod表示允许任何方法;AllowAnyHeader表示允许任何消息头。
    //如果是允许指定的域、方法、消息头需要使用WithOrigins、WithMethods、WithHeaders方法。
    services.AddCors(options =>
    {
        options.AddPolicy("Cors", builder =>
        {
            builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
        });
    });

    ////允许一个或多个来源可以跨域
    //services.AddCors(options =>
    //{
    //    options.AddPolicy("CustomCors", policy =>
    //    {
    //        // 设定允许跨域的来源,有多个可以用','隔开
    //        policy.WithOrigins("http://localhost:9000")
    //        .AllowAnyHeader()
    //        .AllowAnyMethod()
    //        .AllowCredentials();
    //    });
    //});
    #endregion

    services.AddControllers();
}
  1. 在 HTTP 请求管道中调用跨域配置
    添加一句代码即可,但名称一定要与服务中定义的名称一致。对 UseCors 的调用必须放在 UseRouting 之后,但在 UseAuthorization 之前。示例代码如下:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    //添加日志中间件
    app.UseLog();

    //全局捕捉异常
    app.UseExceptionMiddleware();

    app.UseHttpsRedirection();
    app.UseRouting();

    //跨域
    app.UseCors("Cors");
    //app.UseCors("CustomCors");

    //用户认证
    app.UseAuthentication();
    app.UseAuthorization();

    // 添加Swagger有关中间件
    app.UseSwagger();
    app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "API Demo v1"); });

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

不过,仅完成上述配置,将 WebApi 代码发布到本地的 IIS 中测试时,可能依然无法解决跨域问题。

2、IIS 服务器配置

如果是本地访问 WebApi,上述 WebApi 配置方式没问题,但发布到线上就不行了,还需要完成 IIS 服务器的配置:

  1. 在 IIS 中添加一个创建一个自签名的证书。
  2. 在新建 WebApi 网站时,选择 https 协议,配置创建的证书。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

完成以上 3 个步骤,本地访问 IIS 发布的 WebApi 的接口,跨域问题即可解决。如果是发布的 Web 网站访问发布的 WebApi,同样需要对网站进行证书配置。

其他相关说明

  1. 在 html 头部加 <meta http-equiv="Content - Security - Policy" content="upgrade - insecure - requests"> 代码,线上使用无效,但添加后不会报错。
  2. 在控制器加 [EnableCors("{Policy String}")] 中间件属性,可对部分接口或控制器进行跨域配置,若为全局跨域则没必要添加。

本地跨域和线上跨域解决方式有所不同,线上多了一个 IIS
配置。解决跨域问题时,要明确自己对应的方式。后端解决跨域问题相对容易,不建议将该问题交给前端处理。

更多推荐