c# - Angular2 中的 Http PUT 到 .NET Core Web API 在预检请求中出现 http 401 错误

标签 c# angular asp.net-core cors asp.net-core-webapi

我有一个 Angular2 应用程序,它对 .NET Core Web API Controller 执行 http PUT。当我运行该应用程序时,它首先发出 OPTIONS 预检请求并抛出 401 Unauthorized 错误。

XMLHttpRequest cannot load http://localhost:55137/api/Foo/2. Response for preflight has invalid HTTP status code 401

我尝试直接从 Postman 执行 PUT,效果很好。不知道这是否相关,但我从 Angular 应用程序获取的数据也工作正常。我在文档和网络搜索的帮助下整理了以下代码,但我没有完全理解为什么 OPTIONS 飞行前请求未经授权?我尝试了一些方法,例如在 web.config 中删除并重新添加 OPTIONSVerbHandler 。我还了解到,预检请求要求您不要发送凭据,但我不确定在我的情况下如何执行此操作。

我使用 Angular 2.0.0-rc.5 和 .NET Core 1.0.0,并托管在 IIS 8.5 上(在 Visual Studio 2015 中开发时使用 IISExpress)。

foo.service.ts:

import { Injectable } from "@angular/core";
import { Headers, Http, RequestOptions } from "@angular/http";
import { CONFIG } from "./../app.config";

@Injectable()
export class FooService {
    private _apiUrl: string = CONFIG.generalAPI;
    private _headers: Headers = new Headers({ "Content-Type": "application/json" });

    constructor(private http: Http) { }

    updateObj(fooObj: any): Promise<any> {
        let body: any = JSON.stringify(fooObj);
        let options: RequestOptions = new RequestOptions({
            headers: this._headers,
            withCredentials: true
        });
        let result: Promise<any> = this.http.put(this._apiUrl + "/Foo/" + fooObj.ID, body, options)
            .toPromise()
            .then(response => response.json())
            .catch(this.handleError);
        return result;
    }

    private handleError(error: any): Promise<any> {
        console.error("An error occurred", error);
        return Promise.reject(error.message || error);
    }
}

fooController.cs:

// PUT api/Foo/5
[HttpPut("{id}")]
public IActionResult Put(int id, [FromBody]FooClass obj)
{
    try
    {
        _fooService.UpdateFoo(obj);
        return Ok();
    }
    catch (Exception ex)
    {
        return BadRequest("An error occurred. Message: " + ex.Message);
    }
}

webAPI 应用程序的 web.config:

<customHeaders>
    <add name="Access-Control-Allow-Credentials" value="true" />
    <add name="Access-Control-Allow-Origin" value="http://localhost:44612" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept, Authorization" />
</customHeaders>

最佳答案

您可以在 ASP.NET Core Web api 中像这样启用 CORS,而不是 web.config-

首先,在project.json中添加依赖项 - "Microsoft.AspNetCore.Cors": "1.0.0",

然后在 startup.cs 中启用 CORS,如下所示 -

app.UseCors(builder => {
    builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().AllowCredentials();
});

如果您想限制特定来源,那么您可以这样做-

app.UseCors(builder => builder.WithOrigins("example.com"));

您可以找到有关 CORS 的更多信息 here

关于c# - Angular2 中的 Http PUT 到 .NET Core Web API 在预检请求中出现 http 401 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39801670/

相关文章:

c# - 将 Grid.MVC 数据导出到 Excel

c# - 当方法包含 'ref' 参数时创建委托(delegate)的最简单方法

在 ts 代码中带有 i18n 的 Angular 6 应用程序

angular - 为什么我在导入文本编码 polyfill 后在 IE11 中得到 "ReferenceError: ' TextEncoder' is undefined”?

c# - 仅在 DataGrid 中输入数字

c# - 如何从代码隐藏返回字符串并显示在网页上?

angular - 使用 Angular 返回 404 的路由

asp.net-core - 如何在 ASP-all-route-data 中指定 Dictionary<string,string> 以传递查询字符串

asp.net-core - Asp.Net 核心 Swashbuckle 设置 operationId

c# - ASP.NET Core WebApp 不是基于 Travis CI 构建的