【问题标题】:Why doesn't CORS work in ASP.NET Core 3 Web Api?为什么 CORS 在 ASP.NET Core 3 Web Api 中不起作用?
【发布时间】:2019-12-17 13:19:58
【问题描述】:

我尝试基于 ASP.NET Core 3 编写简单的 Web Api。但我对 CORS 策略有疑问。那是我的 Startup 课程:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        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.AddControllers();
        services.AddCors();
    }

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

        app.UseRouting();

        app.UseCors(
            options => options.WithOrigins("http://myorigin.com").AllowAnyMethod().AllowAnyHeader()
        );

        app.UseForwardedHeaders(new ForwardedHeadersOptions
        {
            ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
        });

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

这就是我从前端调用它的方式:

function api_call()
    {
        var form = document.forms["userForm"];
        $.ajax({
            type: "GET",
            url: "http://myorigin.com:8080/access",
            contentType: "application/json",
            crossDomain:true,
            success: function (worker) {
                form.elements["result"].value = worker;
            },
            error: function (jxqr, error, status) {
                console.log(jxqr);
                if(jxqr.responseText===""){
                    form.elements["result"].value = jxqr.statusText;
                }
                else{
                    var response = JSON.parse(jxqr.responseText);
                    console.log(response);
                    if (response['Auth']) {
                        $.each(response['Auth'], function (index, item) {
                            form.elements["result"].value = item;
                        });
                    }
                }
            },
        });
    }

但此函数无法访问 API。它返回请求被 CORS 策略阻止的消息:

对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。

我尝试通过不同的文章以不同的方式使用 CORS。我还尝试添加手动 CORS 中间件,但结果相同。 我的 Web Api 托管在 Ubuntu 上,由 kestrel 服务运行而不会出错。此外,当我在 Visual Studio 中本地运行它并在我的 JS 函数路径中写入本地主机(url:“http://localhost:56597/access”)时,它会调用 API 并成功从中获取响应。

我的错误是什么?我的前端和 Web Api 位于同一主机上,但监听不同的端口。

【问题讨论】:

  • 我猜你的调用 web 应用程序没有在端口 80 上运行。当你第一次创建项目时,IIS Express 的默认端口是随机设置的,而 kestrel 托管通常默认为 5000/5001。您没有指定任何内容,这意味着端口 80。不同的端口是不同的来源(除了旧的 Internet Explorer 浏览器威胁它是相同的来源)
  • @tseng 我为 Apache 设置了从 8080 到 5000 的转发请求,这由 kestrel 和我的 API 使用。
  • 是的,但是您的代码中有.WithOrigins("http://myorigin.com"),这意味着端口 80(这是默认的 http 端口)。 80 != 8080
  • @tseng 是的,因为我从位于默认 80 端口的前端向 apache 监听的 8080 发送请求以在 api 上转发。所以我需要使用 CORS 中的默认端口解析我的来源,因为 api 会从中获取请求。无论如何,现在它正在工作。

标签: asp.net-core asp.net-web-api asp.net-ajax


【解决方案1】:

我建立了自己的错误。我忘了在我的配置方法中添加这个:

app.UseAuthentication();

我在一篇文章中读到,在我的情况下需要它。 我的 Web Api 的 Apache 配置也有错误。我有这样的参数:

ProxyPass / http://localhost:5000/
ProxyPassReverse / http://localhost:5000/

但他们应该是这样的:

ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/

现在我的 Web Api 正在工作,CORS 没有问题。

【讨论】:

  • 取决于您添加身份验证的位置。一般需要在 Cors 中间件后面加上 Auth:docs.microsoft.com/en-us/aspnet/core/migration/…。如果您在 Cors 之前添加 .UseAuth,这可能会导致未经身份验证的用户或预检出现问题
猜你喜欢
  • 2020-03-30
  • 2019-07-09
  • 2021-02-22
  • 1970-01-01
  • 1970-01-01
  • 2019-12-01
  • 2021-11-07
  • 2020-11-01
  • 2014-06-13
相关资源
最近更新 更多