失败http.post与Angular2,到ASP.NET核心API

问题描述:

我试图创建到博客上发表评论,基本能力,使用了以下错误的POST请求我的API Angular2:失败http.post与Angular2,到ASP.NET核心API

Error in comment.service: Response with status: 0 for URL: null 

的形式提交按钮调用我的评论部分,comment-form.component.ts

onSubmit() { 
    this.submitted = true; 

    //TODO: replace hardcoded with form fields 
    this.newComment = new CommentInputViewModel("temp", 0, 0, true, "null", 0); 
    this.newComment.text = this.model.text; 
    this.newComment.ownerID = 6; 
    this.newComment.parentID = 1305; 
    this.newComment.score = 0.5; 
    this.newComment.isFact = true; 
    this.newComment.sideID = 1073; 
    this.newComment.sideText = "For"; 


    this._postService.postNewComment(this.newComment) 
      .subscribe(comment => this.returnedComment = comment, 
       error => this.errorMessage = <any>error); 
     console.log("commentList.component - After onSubmit:" + this.returnedComment); 
    return JSON.stringify(this.model); 
} 

其中要求我服务的API:

postNewComment(newComment: IComment): Observable<IComment>{ 
    let _body = JSON.stringify(newComment); 
    let _headers = new Headers(); 
    _headers.append('Content-Type', 'application/json'); 
    let _options = new RequestOptions({ headers: _headers }); 

    return this._http.post(this._postNewCommentUrl, _body, _options) 
         .map((res:Response) => res.json().value) 
         .catch(this.handleError); 
} 

在API方面的结果,从VS2015调试器是一个204错误(无内容):

![enter image description here] 1

我已经试过:

  1. 排除COR问题。这里的大部分其他Angular2 POST问题都是COR问题。由于请求正在击中我的Visual Studio调试器并返回204,所以我不认为是这样。再加上我CORE startup.cs有“builder.AllowAnyOrigin();作为一项政策从相同的服务,相同的API做工精细

  2. GET命令,我可以阅读我以前在API端创建注释

  3. 拦截与邮差呼叫产生以下:

    The Content-Type header is missing.

    POSTMAN response

    如果我通过改变修改邮递员请求'文本'json和粘贴在模型中,它工作正常。它击中API的“Post”方法并返回200,并且json文本为“true”。见下文。

    enter image description here

它看起来像的身体和头部不被传送。在调试器中都得到传递到后端Angular2代码:

enter image description here

如下建议,这里的开发工具撷取画面。与POSTMAN显示几乎相同的东西。

enter image description here

+0

你应该得到一个OPTIONS调用*,然后是* POST。 204不是错误;这意味着服务器没有要发送的内容,而不是传入的请求没有内容。如果请求格式不正确,你会得到一个4xx错误。 – jonrsharpe

+0

同意,尽管服务器正在发送204,因为angular2 POST不起作用。当它工作时(使用POSTMAN),它返回json'true'和一个200.我修改了上面的问题,以显示当Visual Studio发送帖子时命中的控制器方法,当我的angular2方法执行时,副本会被调用。 – Jason

+1

您是否尝试调试ASP.NET核心应用程序以查看在那里是否发生了任何事情?此外,您是否测试了是否可以从浏览器上下文(CORS未完成)调用该服务?您看到的OPTIONS请求是预期的;缺少的是后续的POST请求(其中会包含您的数据)。我看到你使用的是Firefox,你可以在Chrome中试用吗? Chrome通常会显示更多有关CORS请求失败的信息。 – poke

一个CORS问题。 :/

简而言之,我的ASP.NET CORE startup.cs有'builder.AllowAnyOrigin',而这一点是不够的。它还需要'builder.AllowAnyMethod'来解释Firefox/Google的OPTION方法。这个博客是很好的: https://weblog.west-wind.com/posts/2016/Sep/26/ASPNET-Core-and-CORS-Gotchas

详细信息:

正如我上面提到的,我在ASP.NET CORE CORS是:

services.AddCors(options => 
     { 
      options.AddPolicy("CorsDevPolicy", builder => 
      { 
       builder.AllowAnyOrigin(); 
      }); 

     }); 

我一直在使用Firefox和Chrome。我在IE中试过了,它工作。事实证明,IE不执行飞行前OPTION请求,这是唯一被拒绝的请求。

ASP.NET CORE对CORS文档较弱,所以我用这个博客: https://weblog.west-wind.com/posts/2016/Sep/26/ASPNET-Core-and-CORS-Gotchas

,并修改了我的API的startup.cs文件阅读:

// in the ConfigureServices(IServiceCollection services) method 
services.AddCors(options => 
     { 
      options.AddPolicy("CorsDevPolicy", builder => 
      { 
       builder.AllowAnyOrigin() 
         .AllowAnyMethod() 
         .AllowAnyHeader() 
         .AllowCredentials(); 
      }); 

     }); 

然后(也启动.cs):

public async void Configure(IApplicationBuilder app, ...... 
    { 
     // other unrelated code 

     app.UseCors("CorsDevPolicy"); 
     // other unrelated code. 

     // app.UseCors must come before this: 
     app.UseMvc(); 

欣赏所有评论。他们不停地拨动我尝试新的东西,我不会想到其他方面(如使用IE)。

你想用application/jsoncontent-type,但是在发送体作为一个字符串:let _body = JSON.stringify(newComment);

应该是:const _body = newComment;

+0

欣赏答复,不幸的是没有奏效。来自Angular2调试器(我正在使用VS代码)和来自API调试器(使用VS2015)的相同响应相同的错误。唯一的区别是当我用POSTMAN拦截它时,它有一个额外的头文件:Content-Type,其值为'application/x-www-form-urlencoded'。我相信json.stringify是正确的。 https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify – Jason

+1

是的,角度会做到这一点,如果你不是。我的错。请查看浏览器开发工具发送的角度。 – mxii

+0

谢谢,不用担心。开发工具显示与POSTMAN相同的功能,基本上是发送一个空的OPTION。但是,这是一个好主意,我会继续并使用开发工具的屏幕截图编辑我的问题。 – Jason

对于那些照顾或像我这样的人,不喜欢拥有完全放任的CORS策略的想法。

如前所述,这个问题是一个CORS问题,而CORS头文件指出你朝着正确的方向发展,尽管方式微妙。

在邮递员和开发者工具画面二者捕获上述它们显示一个OPTIONS请求是向服务器发出与所述首标:

Access-Control-Request-Method: POST  
Access-Control-Request-Headers: content-type 

本质上,询问是否该内容 - 类型报头是从POST请求可接受指定的原点。由于CORS策略中没有设置.AllowAnyHeader()或.WithHeaders(“content-type”),因此服务器没有响应并且实际的POST永远不会被浏览器发送。

我最后的政策看起来是这样的:

appBuilder.UseCors(options => 
{ 
    options.WithOrigins("http://myorigin") 
     .WithMethods("POST") 
     .WithHeaders("content-type") 
}); 

我花了比它应该做的图了这一点,所以如果它可以节省别人一些时间这篇文章是值得一吨多的时间:)