【发布时间】:2017-02-09 15:08:45
【问题描述】:
我有一个 Angular2 应用程序,它对 .NET Core Web API 控制器执行 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 应用程序的 GET 也可以正常工作。我已经在文档和网络搜索的帮助下汇总了以下代码,但我还没有完全理解为什么 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 MVC 中使用 [EnableCors()] 属性完成了它,我不知道这是否适用于您的框架,但我知道尝试使用自定义标题伪造它不是预期的方法。
-
如果您使用的是
.NET Core 1.0.0,您如何使用web.config? -
如果您在 IIS 或 IISExpress 下托管,您仍然使用 web.config。
-
你确定它加载正确吗?你可以在中间件中做同样的事情。
-
你在 webapi 控制器上有
Authorize属性吗?如果是,它可能会在来自 Angular 的请求中期待Authorization标头。但根据您的代码,您只传递content-type标头。
标签: c# angular asp.net-core cors asp.net-core-webapi