CORS预检请求被阻止.Net Core 2.2 [重复]

Posted

技术标签:

【中文标题】CORS预检请求被阻止.Net Core 2.2 [重复]【英文标题】:CORS Preflight Requests are being blocked .Net Core 2.2 [duplicate] 【发布时间】:2021-08-26 21:56:46 【问题描述】:

我正在尝试从我的 Angular 前端向 Canada Posts Get Rate API 发出请求。不幸的是,我的后端 .Net Core 2.2 似乎阻止了所有预检请求。如果我尝试使用禁用网络安全标志的 chrome 浏览器发出这些请求,我可以完成请求,但不幸的是,在正常浏览时我无法完成请求。我已尝试在这里阅读许多线程,并在 .NET 文档中指定了 cors 异常,但似乎预检请求仍被阻止。

错误信息: 从源“http://localhost:4200”访问“https://soa-gw.canadapost.ca/rs/ship/price”的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:它没有 HTTP ok 状态。

picture of error

我引用的一些文档没有成功,我尝试向 C# 添加额外的 cors 权限,但预检请求仍然被阻止。 https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-5.0 https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/enabling-cross-origin-requests-in-web-api#how-cors-works

我也无法修改前端 http 标头以删除预检检查,因为其中一些是加拿大邮政 api 所要求的。 https://origin-www.canadapost.ca/info/mc/business/productsservices/developers/services/rating/getrates/default.jsf

前端调用

        const httpOptions = 
                    headers: new HttpHeaders(
                      'Content-Type':  'application/vnd.cpc.ship.rate-v4+xml', //<- To SEND XML
                      'Accept':  'application/vnd.cpc.ship.rate-v4+xml',       //<- To ask for XML                                 //<- b/c Angular understands text
                      'Authorization': 'Basic YTUxZGQ1MWY2YjJhNjE4ODowODgzOThiZTUxY2Y4Y2RjZTIzM34',
                      'Accept-language': 'en-CA',
                      'Access-Control-Allow-Origin': '*',
                      "Access-Control-Allow-Methods": "DELETE, POST, GET, OPTIONS",
                    ),
                     
                    responseType: 'text' as 'json'
                  ;

    var  postedData = `
                    <mailing-scenario xmlns="https://www.canadapost.ca/ws/ship/rate-v4">
                    <customer-number>0009669089</customer-number>
                    <parcel-characteristics>
                    <weight>5 </weight>
                    </parcel-characteristics>
                    <origin-postal-code>M5V0G1</origin-postal-code>
                    <destination>
                    <domestic>
                    <postal-code>M4R1L8</postal-code>
                    </domestic>
                    </destination>
                    </mailing-scenario>
                    `;
// http post to canada post using angular httpclient
         this.http.post('https://soa-gw.canadapost.ca/rs/ship/price', postedData, httpOptions)
                    .subscribe(
                      result =>     
                console.log(result);                 
                      , 
                      error => console.log('There was an error: ', error));

后端启动.cs

using AutoMapper;
using Domain;
using Domain.Entities;
using Domain.Entities.Projects;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Internal;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Rolox.Domain.Entities;
using Server.Classes;
using Server.Interfaces;
using Server.Models;
using System;
using System.IO;

namespace Server

    public class Startup
    
        public Startup(IConfiguration configuration, IHostingEnvironment env)
        
            Configuration = configuration;
        

        public IConfiguration Configuration  get; 

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        

            services.AddCors(options =>
            
                options.AddDefaultPolicy(
                    builder =>
                    
                        builder.WithOrigins("*")
                               .AllowAnyHeader()
                               .AllowAnyMethod();
                    );
                
                options.AddPolicy("MyAllowAllHeadersPolicy",
                    builder =>
                    
                        builder.WithOrigins("*").AllowAnyMethod()
                               .AllowAnyHeader();
                    );

            );



            services.Configure<CookiePolicyOptions>(options =>
            
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => false;
                options.MinimumSameSitePolicy = SameSiteMode.None;

            );
         
            services.AddSwaggerDocument();

            services.AddDbContext<RoloxDbContext>(options =>
                 options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
                 providerOptions => providerOptions.EnableRetryOnFailure()));

            services.AddDefaultIdentity<User>()
                .AddRoles<Role>()
                .AddEntityFrameworkStores<RoloxDbContext>();

            /// Auto Mapper Configurations
            var mappingConfig = new MapperConfiguration(mc =>
            
                mc.AddProfile(new MappingProfile());
            );
            IMapper mapper = mappingConfig.CreateMapper();
            services.AddSingleton(mapper);

            ConfigureRepositories(services);

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            services.Configure<SettingModel>(Configuration.GetSection("Settings"));

            services.AddMvc().AddJsonOptions(options =>
            
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
                options.SerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;


            );

            services.Configure<FormOptions>(options =>
            
                options.MemoryBufferThreshold = Int32.MaxValue;

            );
        

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        
            app.UseCors("MyAllowAllHeadersPolicy");

            app.UseOpenApi();
            app.UseSwaggerUi3();

            if (env.IsDevelopment())
            
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            
            else
            
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            

         
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();
            app.UseStaticFiles();
            app.UseAuthentication();

            app.UseMvc(routes =>
            
                routes.MapRoute(
                    name: "default",
                    template: "controller=Home/action=Index/id?");
            );


            app.UseSpa(spa =>
            
            );
        

        private void ConfigureRepositories(IServiceCollection services)
        
            /// Repository Injections
            services.AddScoped<IRoloxRepository<ProposalStage>, ProposalStageRepository>();
            services.AddScoped<IProposalRepository, ProposalRepositoy>();
            services.AddScoped<IRoloxRepository<ChecklistItem>, ChecklistRepository>();
            services.AddScoped<IRoloxRepository<Contractor>, ContractorRepository>();
            services.AddScoped<IRoloxRepository<Project>, ProjectRepository>();
            services.AddScoped<IDirectCostRepository, ProjectDirectCostRepository>();
            services.AddScoped<IInvoiceRepository, InvoiceRepositoy>();
            services.AddScoped<ICompanyProfileRepository, CompanyRepository>();
        
    

解决方案:从生产中发送消息,前端预检请求被阻止,而是从后端服务器发送 api 调用。尽管在实时使用中禁用网络安全进行测试,但它必须从后端发送。

【问题讨论】:

除非您的服务器域名是“soa-gw.canadapost.ca”,否则CORS错误与您的ASP.NET服务器配置无关。此外,CORS 标头(“Access-Control-Allow-”)是 *response 标头,而不是请求标头,因此将它们包含在请求中没有好处。 可能对你有帮助:***.com/questions/40547836/… 【参考方案1】:

对一些 CORS 的东西有同样的问题,出于测试目的,我只添加了这些行以使其正常工作。从长远来看,这可能不是最好的,但是。它可能会让它运行。在启动时的 ConfigureServices 中添加:

services.AddCors();

然后在配置中添加这个:

 app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

我把 services.AddCors();在 ConfigureServices 和 app.UserCors... 之间的顶部 app.UseRouting();和 app.UseAuthorization();

希望这对你有用。

【讨论】:

我试过了,但仍然有相同的预检错误消息。在我的应用程序中,我没有调用 app.UseRouting();或 App.UseAuthorization();在这种情况下你会把它放在哪里?我已经在配置顶部和 app.UseMvc() 之后尝试过

以上是关于CORS预检请求被阻止.Net Core 2.2 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

跨域请求被阻止原因:CORS 预检通道未成功

角 POST 请求被 CORS 策略阻止:对预检请求的响应未通过访问控制检查

请求被 CORS 阻止:对预检请求的响应未通过访问控制检查:它没有 HTTP ok 状态

被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:它没有 HTTP OK 状态

来自 ASP NET Web API 的 CORS 阻止 Ajax POST 调用 - 对预检请求的响应未通过访问控制检查

被 CORS 阻止:预检响应中的 Access-Control-Allow-Headers 不允许请求标头字段授权