简体   繁体   English

Web Api 2适用于邮递员,但使用Angular 2失败

[英]Web Api 2 works with postman but fails with Angular 2

Postman request: 邮差要求: 在此输入图像描述

Everything works great with postman. 邮递员一切都很好。 I posted Bearer token on server and got expected result. 我在服务器上发布了Bearer令牌并得到了预期的结果。

Angular 2 request: Angular 2请求:

    //app component
    test(){
        return this.httpService.get('api/user/get', 'application/json')
          .subscribe(data=>{
              console.log({'loggedIn': true, 'messageText': 'test succeeded'});
            },
            error=>{
              console.log({'loggedIn': false, 'messageText': error});
            }
          );
      }

//http-service
get(url:string, contentType:string):Observable<any> {
    let baseUrl:string = "http://localhost:1382/";

    let headers = new Headers({
      'Accept': 'application/json'
    });

    //append content-type to headers
    headers.append('Content-type', contentType);

    //check if localStorage contains token. If yes, append authorization to headers
    let token = localStorage.getItem('access_token');
    if (token !== '[object Object]' && token !== null) {
      headers.append('Authorization', 'Bearer' + ' ' + token);
    }

    let requestOptions = new RequestOptions({headers: headers});

    //send get request
    return this.http.get(baseUrl + url, requestOptions)
      .map((res:Response)=>res.json())
      .catch(this.handleError);
  }

And it says error: 它说错误:

OPTIONS http://localhost:1382/api/user/get 405 (Method Not Allowed)

XMLHttpRequest cannot load http://localhost:1382/api/user/get. Response for preflight has invalid HTTP status code 405

<Error>
<Message>Authorization has been denied for this request.</Message>
</Error>

I enabled CORS in Web Api 2 web.config like following: 我在Web Api 2 web.config中启用了CORS,如下所示:

<system.webServer>
<httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization, Accept" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>

Any suggestions? 有什么建议么?

It works in postman because that is an extension, it just sends the request. 它适用于邮递员,因为这是一个扩展,它只是发送请求。
On the other hand when sending from a browser, for security reasons, requests are sent differently. 另一方面,当从浏览器发送时,出于安全原因,请求的发送方式不同。
First the browser sends an OPTIONS request (so called preflight request) to http://foo.com/bar . 首先,浏览器向http://foo.com/bar发送OPTIONS请求(所谓的预检请求)。 This is to determine whether it is acceptable to send the request with these parameters. 这是为了确定使用这些参数发送请求是否可接受。
Your backend should handle the request, respond and set response headers like: 您的后端应该处理请求,响应并设置响应标头,如:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Headers
  • Access-Control-Allow-Credentials
  • Access-Control-Allow-Methods
  • etc 等等

After that, based on the headers of the OPTIONS response, the browser will send the GET to http://foo.com/bar IF everything is allowed, like origin, method, etc. 之后,根据OPTIONS响应的标题,浏览器会将GET发送到http://foo.com/bar如果允许所有内容,如来源,方法等。

You actually do have a preflight request (failing with 405). 实际上你确实有一个预检请求(失败了405)。

You can see here why, probably due to Content-Type or any other header (X-Requested-With ?). 您可以在这里看到原因,可能是由于Content-Type或任何其他标题(X-Requested-With?)。

If you want to keep this preflight you have to handle it in webapi and disable authorization or at least return 200 (you can take a look here ) 如果你想保留这个预检,你必须在webapi中处理它并禁用授权或至少返回200(你可以看看这里

Thank you everyone for your answers and advices. 谢谢大家的答案和建议。 I summed up all this information and in addition I found this answer: https://stackoverflow.com/a/39397016/4559099 in GrantResourceOwnerCredentials I added context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "http://localhost:4200" }); 我总结了所有这些信息,另外我找到了这个答案: httpsGrantResourceOwnerCredentialsGrantResourceOwnerCredentials我添加了context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { "http://localhost:4200" });

And in WebApiConfig I added config.EnableCors(new EnableCorsAttribute("http://localhost:4200, ", "*", "*")); WebApiConfig我添加了config.EnableCors(new EnableCorsAttribute("http://localhost:4200, ", "*", "*")); and everything works great. 一切都很好。

Actually I didn't understand why comment's author wrote config.EnableCors(new EnableCorsAttribute("http://localhost:4200, ", "*", "*")); 实际上我不明白为什么评论的作者写了config.EnableCors(new EnableCorsAttribute("http://localhost:4200, ", "*", "*")); instead of config.EnableCors(new EnableCorsAttribute("http://localhost:4200", "*", "*")); 而不是config.EnableCors(new EnableCorsAttribute("http://localhost:4200", "*", "*")); But it works fine. 但它运作正常。 It will be really helpful if someone explains this. 如果有人解释这将是非常有帮助的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM