关于c#:ASP.NET Core CORS WebAPI:没有Access-Control-Allow-Origin标头

ASP.NET Core CORS WebAPI: no Access-Control-Allow-Origin header

我已经将ASP.NET核心Web API部署到Azure,我可以使用Swagger或像Fiddler这样的Web调试器访问其端点。在这两种情况下(Swagger中的相同来源,使用来自我的计算机的Fiddler的不同来源),当访问API时,我获得了预期的结果,在我的Startup.cs中启用了CORS,如下所示:

  • services.AddCors();添加到ConfigureServices

  • 将中间件添加到Configure:我知道这里的顺序很重要(ASP.NET 5:响应中的Access-Control-Allow-Origin),所以我将此调用放在方法的顶部,只有在记录之前或诊断中间件;这是我的完整方法:

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    public void Configure(IApplicationBuilder app, IHostingEnvironment env,
        ILoggerFactory loggerFactory,
        IDatabaseInitializer databaseInitializer)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();
        loggerFactory.AddNLog();

        // to serve up index.html
        app.UseDefaultFiles();
        app.UseStaticFiles();

        // http://www.talkingdotnet.com/aspnet-core-diagnostics-middleware-error-handling/
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();

        // CORS
        // https://docs.asp.net/en/latest/security/cors.html
        app.UseCors(builder =>
                builder.WithOrigins("http://localhost:4200","http://www.myclientserver.com")
                    .AllowAnyHeader()
                    .AllowAnyMethod());

        app.UseOAuthValidation();
        app.UseOpenIddict();
        app.UseMvc();

        databaseInitializer.Seed().GetAwaiter().GetResult();
        env.ConfigureNLog("nlog.config");

        // swagger
        app.UseSwagger();
        app.UseSwaggerUi();
    }

    localhost CORS在开发期间使用,指的是Angular2 CLI应用程序。 CORS在本地工作正常,我的客户端和API应用程序位于同一个本地主机上的不同端口上,所以这是"真正的"交叉起源(我正在评论这个,因为我在这里找到的建议:https://weblog.west -wind.com/windts/2016/Sep/26/ASPNET-Core-and-CORS-Gotchas:帖子的作者注意到响应中的CORS头只在实际需要时发送,即在真正的跨源环境中)。

    使用Fiddler我可以成功访问远程API,但我得到NO Access-Control-Allow-Origin标头。因此,当从浏览器(通过我的客户端应用程序)调用API时,即使服务器返回200,AJAX请求也会失败。示例Fiddler请求(成功):

    1
    2
    GET http://mywebapisiteurl/api/values HTTP/1.1
    User-Agent: Fiddler

    响应:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    HTTP/1.1 200 OK
    Transfer-Encoding: chunked
    Content-Type: application/json; charset=utf-8
    Server: Microsoft-IIS/8.0
    X-Powered-By: ASP.NET
    Set-Cookie: ARRAffinity=3d551180c72208c1d997584c2b6119cf44e3a55c868f05ffc9258d25a58e95b1;Path=/;Domain=prinapi.azurewebsites.net
    Date: Thu, 01 Dec 2016 10:30:19 GMT

    ["value1","value2"]

    当尝试访问部署在Azure上的远程API时,我的客户端应用程序始终会失败其AJAX请求并显示错误:

    1
    No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://www.myclientserver.com' is therefore not allowed access.

    以下是使用Angular2的示例客户端代码(使用Plunker):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    import {Component, NgModule} from '@angular/core';
    import {BrowserModule} from '@angular/platform-browser';
    import { Http, Headers, Response } from '@angular/http';
    import { HttpModule } from '@angular/http';

    @Component({
      selector: 'my-app',
      template: `
       
          Hello {{name}}
          <button (click)="test()">test</button>
       
      `,
    })
    export class App {
      name:string;
      constructor(private _http: Http) {
        this.name = 'Angular2'
      }
      public test() {
        this._http.get('http://theapisiteurlhere/api/values',
        {
            headers: new Headers({
              'Content-Type': 'application/json'
            })
        })
        .subscribe(
          (data: any) => {
            console.log(data);
          },
          error => {
            console.log(error);
          });
      }
    }

    @NgModule({
      imports: [ BrowserModule, HttpModule ],
      declarations: [ App ],
      bootstrap: [ App ]
    })
    export class AppModule {}

    总而言之,似乎ASPNET API服务器没有返回预期的CORS头,因此托管在不同源上的基于浏览器的客户端失败。然而,CORS设置似乎没问题,至少从上面引用的文档判断;我处在真正的跨性别环境中;我把中间件放在其他人之前。也许我错过了一些明显的东西,但谷歌搜索这些是我发现的所有建议。任何提示?

    UPDATE

    回复@Daniel J.G:来自提琴手的请求/回复是成功的:

    1
    2
    3
    4
    GET http://theapiserver/api/values HTTP/1.1
    User-Agent: Fiddler
    Host: theapiserver
    Origin: http://theappserver/apps/prin

    和:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Server: Microsoft-IIS/8.0
    Access-Control-Allow-Origin: http://theappserver/apps/prin
    X-Powered-By: ASP.NET
    Set-Cookie: ARRAffinity=3d551180c72208c1d997584c2b6119cf44e3a55c868f05ffc9258d25a58e95b1;Path=/;Domain=theapiserver
    Date: Thu, 01 Dec 2016 14:15:21 GMT
    Content-Length: 19

    ["value1","value2"]

    据报道,Angular2(Plunker)的请求/响应失败了。通过检查网络流量,我只能看到预检请求:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    OPTIONS http://theapiserver/api/values HTTP/1.1
    Host: theapiserver
    Proxy-Connection: keep-alive
    Access-Control-Request-Method: GET
    Origin: http://run.plnkr.co
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36
    Access-Control-Request-Headers: content-type
    Accept: */*
    Referer: http://run.plnkr.co/h17wYofXGFuTy2Oh/
    Accept-Encoding: gzip, deflate, sdch
    Accept-Language: en-US,en;q=0.8,it;q=0.6

    HTTP/1.1 204 No Content
    Server: Microsoft-IIS/8.0
    X-Powered-By: ASP.NET
    Set-Cookie: ARRAffinity=3d551180c72208c1d997584c2b6119cf44e3a55c868f05ffc9258d25a58e95b1;Path=/;Domain=theapiserver
    Date: Thu, 01 Dec 2016 14:23:02 GMT

    此后,请求失败,没有更多流量进入服务器。报告的问题是Response to preflight request doesn't pass access control check,同样是因为响应中缺少标题:

    1
    XMLHttpRequest cannot load http://theapiserver/api/values. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://run.plnkr.co' is therefore not allowed access.


    以下是我自己的问题的答案,从评论中复制:我没有注意到在Azure门户中有一个CORS部分。如果我没有在那里输入任何允许的来源,我的基于代码的配置似乎完全无关紧要。这对我来说很奇怪,因为我不得不在这里复制URL,但是一旦我将*添加到允许的来源那里就可以了。


    添加.AllowAnyHeader()方法可以解决您的问题

    1
    2
    3
    app.UseCors(builder => builder.WithOrigins("http://localhost:4200")
                                  .AllowAnyMethod()
                                  .AllowAnyHeader());


    错误消息非常错误。尝试将新表添加到DbContext后,我收到了同样的错误。 Angular没有给出"Access-Control-Allow-Origin"错误,但是Postman给出了500内部服务器错误。尝试调用_userManager.FindByEmailAsync()时,Login方法失败。希望这有助于其他人。


    WebApi项目--->右键单击"管理Nuget包"部分中的"参考文献--->搜索核心"。通过安装将Microsoft.AspNet.WebApi.Cors添加到项目中

    将以下代码添加到项目中App_Start文件夹下的WebApi.Config文件中。

    var cors = new EnableCorsAttribute(",","*");
    config.EnableCors(CORS);

    在此输入图像描述

    在此输入图像描述