跨源请求被阻止——使用 Angular 和 ASP.NET Core 构建的应用程序

Pho*_*eng 5 c# asp.net-core angular

我正在使用 Angular 和 ASP.NET Core 构建一个网站。

\n

在某些页面上,我想从 Web API 获取数据。当我运行该应用程序时,浏览器(Firefox)显示

\n
\n

跨源请求被阻止:同源策略不允许读取位于...(url)的远程资源(原因:CORS 标头 \xe2\x80\x98Access 中缺少令牌 \xe2\x80\x98authorization\xe2\x80\x99 -来自 CORS 预检通道的 Control-Allow-Headers\xe2\x80\x99)。

\n
\n

我尝试了其他浏览器,得到了同样的错误。

\n

出于授权考虑,我使用 aHttpInterceptor为来自 Angular 前端的每个请求插入授权标头。

\n

然后我查看了 ASP.NET Core 后端。我将 CORS 策略设置为 app.UseCors(builder => { builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(); });,但仍然不起作用。

\n

我用Postman测试了API,效果很好。

\n

哪里出了问题?

\n

文件Startup.cs

\n
public class Startup\n{\n    public Startup(IConfiguration configuration)\n    {\n        Configuration = configuration;\n    }\n\n    public IConfiguration Configuration { get; }\n\n    // This method gets called by the runtime. Use this method to add services to the container.\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddMvc().AddJsonOptions(\n            opt => opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore\n            );\n\n        // In production, the Angular files will be served from this directory\n        services.AddSpaStaticFiles(configuration =>\n        {\n            configuration.RootPath = "ClientApp/dist";\n        });\n\n        services.AddEntityFrameworkSqlServer();\n        services.AddCors();\n        services.AddSignalR();\n\n        services.AddDbContext<ApplicationDbContext>(opt =>\n        {\n            opt.UseSqlServer(Configuration.GetConnectionString("Remote"));\n        });\n\n        services.AddIdentity<ApplicationUser, IdentityRole>(opts =>\n        {\n            opts.Password.RequireDigit = true;\n            opts.Password.RequireLowercase = true;\n            opts.Password.RequireUppercase = true;\n            opts.Password.RequireNonAlphanumeric = false;\n            opts.Password.RequiredLength = 7;\n        }).AddEntityFrameworkStores<ApplicationDbContext>();\n\n        services.AddAuthentication(opts =>\n        {\n            opts.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;\n            opts.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;\n            opts.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;\n        })\n        .AddJwtBearer(cfg =>\n        {\n            cfg.RequireHttpsMetadata = false;\n            cfg.TokenValidationParameters = new TokenValidationParameters()\n            {\n                ValidIssuer = Configuration["Auth:Jwt:Issuer"],\n                ValidAudience = Configuration["Auth:Jwt:Audience"],\n                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Auth:Jwt:Key"])),\n                ClockSkew = TimeSpan.Zero,\n                RequireExpirationTime = true,\n                ValidateIssuerSigningKey = true,\n                ValidateAudience = true\n            };\n        });\n\n        services.AddAuthorization(options =>\n        {\n            options.AddPolicy("NonUser", policy => policy.RequireRole("RestrauntOwner", "RestrauntAdmin", "SystemAdmin"));\n        });\n    }\n\n    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.\n    public void Configure(IApplicationBuilder app, IHostingEnvironment env)\n    {\n        if (env.IsDevelopment())\n        {\n            app.UseDeveloperExceptionPage();\n        }\n        else\n        {\n            app.UseExceptionHandler("/Home/Error");\n        }\n        app.UseCors(builder => { builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(); });\n        app.UseStaticFiles();\n        app.UseSpaStaticFiles();\n        app.UseAuthentication();\n        app.UseMvc(routes =>\n        {\n            routes.MapRoute(\n                name: "default",\n                template: "{controller}/{action=Index}/{id?}");\n        });\n        app.UseSignalR(route =>\n        {\n            route.MapHub<OrderHub>("/orderhub");\n        });\n        app.UseCookiePolicy();\n        app.UseSpa(spa =>\n        {\n            // To learn more about options for serving an Angular SPA from ASP.NET Core,\n            // see https://go.microsoft.com/fwlink/?linkid=864501\n\n            spa.Options.SourcePath = "ClientApp";\n\n            if (env.IsDevelopment())\n            {\n                spa.UseAngularCliServer(npmScript: "start");\n            }\n        });\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

有点奇怪。我在我的 Windows PC 上开发这个程序已经有一段时间了。我在 MacBook 上克隆了该项目,它在 macOS 上运行良好,没有任何问题。

\n

Sau*_*ala 2

此错误背后的原因是:您的客户端项目和 webapi 位于不同的域(或端口)上。

浏览器安全性可防止网页向另一个域发出 AJAX 请求。此限制称为同源策略,可防止恶意站点从另一个站点读取敏感数据。

要为您的应用程序设置 CORS,请将Microsoft.AspNetCore.Cors包添加到您的项目中。

然后使用中间件启用 CORS:在启动 > 配置服务方法中

//For any origin
public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy("AllowSpecificOrigin",
            builder1 => builder1.WithOrigins("http://web.user.local:44352"));
    });
}
Run Code Online (Sandbox Code Playgroud)

在配置方法中:

public void Configure(IApplicationBuilder app)
{          
    // Shows UseCors with named policy.
    app.UseCors("AllowSpecificOrigin");

    //...rest
}
Run Code Online (Sandbox Code Playgroud)

注意:指定的 URL 必须不带尾部斜杠 (/)。如果 URL 以 / 结尾,则比较将返回 false,并且不会返回标头。

欲了解更多信息,请阅读此处