405(不允许使用方法),并被CORS策略阻止 [英] 405 (Method Not Allowed) and blocked by CORS policy

查看:296
本文介绍了405(不允许使用方法),并被CORS策略阻止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有带基于Angular(7.2.1)的UI的Asp.Net Core(3)WebApi项目. 当使用Postman或仅使用URL时,我可以使用GET和POST而没有任何特定的错误. 当通过Angular(Chrome \ FireFox \ IE浏览器)尝试相同操作时,出现以下错误.

I have Asp.Net Core(3) WebApi project with UI based on Angular(7.2.1) on Client side. When using Postman or just using the URL I can use GET and POST without any particular errors. When trying the same by Angular(Chrome\FireFox\IE Browser) I'm getting the following errors.

zone.js:3243 OPTIONS http://localhost:8888/api/PaymentDetails 405 (Method Not Allowed) ccess to XMLHttpRequest at 'http://localhost:8888/api/PaymentDetails' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

我将尽力分享尽可能多的代码来演示流程.

I'll try to share as much as code I can to demonstrate the flow.

WebApi Startup.cs:

public IConfiguration配置{ }

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.AddPolicy("CorsPolicy",
            builder =>
            builder.AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader()

                );
    });
    services.AddControllers()
        .AddJsonOptions(options =>
        {
            options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
            options.JsonSerializerOptions.PropertyNamingPolicy = null;
        });

    services.AddDbContext<PaymentDetailContext>(options => options.UseSqlServer("Server=DESKTOP-KT0N2RN\\SQLEXPRESS;DataBase=PaymentDetailDB;Trusted_Connection=True;MultipleActiveResultSets=True;"));

}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{


    app.UseRouting();

    app.UseAuthorization();

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

    app.UseCors("CorsPolicy");
}

WebAPi GET方法:

[HttpGet]
public async Task<ActionResult<IEnumerable<PaymentDetail>>> GetPaymentDetails()
{
    return await _context.PaymentDetails.ToListAsync();
}

客户端:

rootUrl: string = "http://localhost:8888/api";

getPaymentDetail()
{

    console.log(`${this.rootUrl}/PaymentDetails`)
    const headers = new HttpHeaders().set('Content-Type','application/json');
    // headers.append('Access-Control-Allow-Origin', '*');
    // headers.append('Access-Control-Allow-Headers','Origin, X-Requested-With, Content-Type, Accept');
    return this._http.get(`${this.rootUrl}/PaymentDetails`,{headers:headers});
}

推荐答案

我认为更改Startup Configure中的以下内容应该可以.注意顺序:按照文档

I think changing the following in Startup Configure should work. Note the order: as per the docs

对于端点路由,必须将CORS中间件配置为在对UseRouting和UseEndpoints的调用之间执行.错误的配置将导致中间件停止正常运行.

With endpoint routing, the CORS middleware must be configured to execute between the calls to UseRouting and UseEndpoints. Incorrect configuration will cause the middleware to stop functioning correctly.

app.UseRouting();

app.UseAuthorization();

app.UseCors("CorsPolicy");

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

我认为对COR进行快速汇总可能有助于解释为什么邮递员请求对您有用.

I think a really quick summary of CORs might be helpful to eexplain why postman requests were working for you.

默认情况下,CORS用于浏览器中,以检查服务器将接受来自哪个来源的请求.

CORS is used in browsers by default to check which origins servers will accept requests from.

如果您对服务器的请求来自相同的来源(来源的所有部分必须匹配),则您的CORS请求不会失败,因为它不是跨来源的.在您的情况下,端口不匹配,因此即使服务器和Web应用程序都在本地主机上运行,​​也因为端口不匹配而被视为交叉源

if your request to the server was from the same origin (all parts of the origin must match) your CORS request would not fail because its not cross origin. In your case the ports to not match so even though both the server and web app are running from your localhost, it counts as cross origin because the ports don't match

发送请求时,浏览器将首先发送选项请求(预检请求),该请求将显示受支持的受支持方法,并检查您的来源(您的前端Web应用程序)是否有权将请求发送到服务器.默认情况下,大多数主要浏览器(Chrome,Firefox,Edge等)都内置了此功能.

When you send a request the browser will first send an Options request (a preflight request) which will show supported supported methods and check if your origin (your front end web app) has permission to send requests to the server. This functionality is built into most main browsers by default (Chrome, Firefox, Edge etc).

您的邮递员请求有效,因为邮递员未发送预检请求.

Your postman request works because postman does not send a preflight request.

进一步阅读:

启用CORS

https://docs.microsoft .com/en-us/aspnet/core/security/cors?view = aspnetcore-3.1

什么是CORS

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS

这篇关于405(不允许使用方法),并被CORS策略阻止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆