【问题标题】:Getting CORS errors on HTTP Post call on frontend在前端的 HTTP Post 调用上获取 CORS 错误
【发布时间】:2021-01-17 07:04:57
【问题描述】:

我编写了一个 Asp.Net Core api,到目前为止它运行良好,但是当我尝试发送一个帖子请求时,它给了我Access to XMLHttpRequest at 'https://localhost:44339/api/drawing/checkout' 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.

我在后端(startup.cs)上启用了 CORS,如下所示:

services.AddCors(options =>
            {
                options.AddPolicy(name: MyAllowSpecificOrigins,
                                  builder =>
                                  {
                                      builder.WithOrigins("http://localhost:4200")
                                      .AllowCredentials()
                                      .AllowAnyHeader()
                                      .AllowAnyMethod();
                                  });
            });

app.UseCors(MyAllowSpecificOrigins);

我已经为此浪费了几天时间,我的 GET 请求以及使用 Insomnia 的 POST 请求都有效。有人可以帮我处理 Angular 部分吗?这是我的代码

在 drawing.service.ts 上:

test(param) {
    return this.http.post(this.url + '/checkout', param, {
      headers: { 'Content-Type': 'application/json' },withCredentials:true
    });
  }

在我的组件 ts 上:

test() {
      let stringfiedArray = JSON.stringify(this.viewerPerm);
      console.log(stringfiedArray);
      this.drawingSearchService.test(stringfiedArray).subscribe();
    }

【问题讨论】:

  • 你能分享一个你的 Insomnia 请求的 URL 示例吗?
  • URL:localhost:44339/api/drawing/checkout,使用NTML认证,发送JSON为body,header为Content-Type application/json
  • 正如我所怀疑的那样。您需要在 CORS 配置中配置您的 API URL。将 https://localhost:44339 添加到您的 CORS 策略来源,然后重试。
  • 您可以在配置中添加多个来源。
  • 我仍然遇到同样的错误

标签: c# angular api asp.net-core cors


【解决方案1】:

从源“http://localhost:4200”访问“https://localhost:44339/api/drawing/checkout”处的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。

使用 HTTP OPTIONS 方法的 CORS 预检请求用于检查 CORS 协议是否被理解以及服务器是否使用特定的方法和标头知道。

而且OPTIONS 请求始终是匿名的,您提到您启用了 NTML 身份验证,这会导致服务器无法正确响应预检请求。

有关“CORS 预检请求”的更多信息,请查看:https://docs.microsoft.com/en-us/iis/extensions/cors-module/cors-module-configuration-reference#cors-preflight-request

如果您想在本地运行您的应用以使用 CORS 进行测试,要解决此问题,您可以尝试启用匿名身份验证以允许匿名访问。

此外,如果您将应用托管在 IIS 服务器上,要解决此问题,您可以安装 IIS CORS module 并为应用配置 CORS。

【讨论】:

    【解决方案2】:

    首先,我将假设您当前的代码可以与另一个 API 服务正常工作,并且可以正常执行 POST 请求。我希望您确实已经测试了您的前端代码,并且已经确定问题仅出在您的 API 服务器上。

    其次,尝试使用默认策略而不是命名策略,看看这是否会有所不同。它看起来像这样。

        //lets add some CORS stuff 
        services.AddCors(options =>
        {
            options.AddDefaultPolicy(builder => {
                builder.WithOrigins("http://localhost:4200");
                builder.AllowAnyMethod();
                builder.AllowAnyHeader();
                builder.AllowCredentials();
            });
        });
    

    之后,在配置中,

        app.UseHttpsRedirection();
    
        app.UseRouting();
    
        app.UseCors(); //it may not matter, but try to put cors between routing and auth.
    
        app.UseAuthorization();
    

    【讨论】:

    • 嘿,我试过你的建议,但没有用。实际上,我不确定我的问题出在哪里,因为我可以正常拨打电话,但不能发帖。你能接受吗看看我的 OP,看看你能不能在我的前端发现什么?
    • 如果这不起作用,那么,我确信,问题出在您的前端。如果我是你,我会做一个基本的 POST 测试。在您的 API 服务器上构建一个简单的 POST 端点。某些东西需要像它的主体一样简单的字符串并返回该字符串。然后,在您的前端应用程序上,使用标准的 JavaScript 提取库调用此测试端点。如果这可行,至少你会知道 CORS 设置正确。
    【解决方案3】:

    您需要在您的 Angular 项目中创建一个 proxy.conf.json 文件,包括以下内容

    {
    "/api": {
      "target": "http://localhost:4200",
      "secure": false,
      "changeOrigin": true,
      "pathRewrite": {
        "^/api": ""
      }
    }
    

    }

    在您调用服务的地方,您将引用代理的 api,如下所示:

    this.http.get(`api/checkout`);
    

    记得使用 ` 字符而不是单引号。

    当你运行你的应用程序时,一定要添加代理文件

    ng serve --proxy-config proxy.conf.json
    

    GUIDE

    在后台,仅供内部使用,请尝试如下设置

    services.AddCors(options =>
        {
            options.AddPolicy("AllowAnyOrigin",
                builder =>
                {
                    builder
                    .AllowAnyOrigin() 
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials();
                });
        });
    

    【讨论】:

    • 我试过了,但它什么也做不了(甚至不会在我的 api 的第一行打断点),chrome 的网络选项卡显示请求状态为“待处理”跨度>
    • 您的 api 正在孤立地返回结果?
    猜你喜欢
    • 2021-08-05
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 2019-06-29
    • 2019-11-15
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    相关资源
    最近更新 更多