【问题标题】:Failed http.post with Angular2, to ASP.NET CORE API使用 Angular2 的 http.post 失败,到 ASP.NET CORE API
【发布时间】:2017-06-07 09:06:35
【问题描述】:

我正在尝试创建在博客上发布 cmets 的基本功能,使用 Angular2 向我的 API 发出 POST 请求时出现以下错误:

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 错误(无内容):

]1

我尝试过的:

  1. 大部分排除了 COR 问题。这里的大多数其他 Angular2 POST 问题都是 COR 问题。由于该请求正在访问我的 Visual Studio 调试器并返回 204,因此我认为不是这样。另外,我的 CORE startup.cs 将“builder.AllowAnyOrigin(); 作为一项政策。

  2. 从同一服务到同一 API 的 GET 命令可以正常工作。我可以读取我之前在 API 端创建的 cmets。

  3. 使用 POSTMAN 拦截呼叫会产生以下结果:

    如果我通过将“文本”更改为 json 并粘贴到模型中来修改 POSTMAN 请求,它可以正常工作。它命中 API 的“Post”方法并返回 200,以及 json 文本“true”。见下文。

似乎没有传输正文和标头。在调试器中,两者都被传递给后端 Angular2 代码:

如下所示,这里是开发工具的屏幕截图。显示的内容与 POSTMAN 几乎相同。

【问题讨论】:

  • 你应该得到一个 OPTIONS 调用后跟一个 POST。 204 不是错误;这意味着服务器没有内容要发回,而不是传入的请求没有内容。如果请求格式不正确,您会收到 4xx 错误。
  • 同意,尽管服务器正在发送 204,因为 angular2 POST 不起作用。当它确实工作时(使用 POSTMAN),它返回 json 'true' 和 200。我在上面修改了我的问题,以显示 Visual Studio 中的控制器方法,该方法在 POSTMAN 发送帖子时受到打击,反之,当我的 angular2 方法发出时。
  • 您是否尝试调试 ASP.NET Core 应用程序以查看那里是否发生了任何事情?此外,您是否测试过是否可以从浏览器上下文(未完成 CORS)外部调用该服务?您看到的 OPTIONS 请求是预期的;缺少的是后续 POST 请求(然后将包含您的数据)。我看到您使用的是 Firefox,您可以在 Chrome 中尝试一下吗? Chrome 通常会显示有关失败的 CORS 请求的更多信息。
  • Poke - 上面的第一个和第四个屏幕截图来自 ASP.NET CORE 端,我在 VS2015 中运行我的 API,在 VS Code 中运行 Angular2 端。我一直在 VS Code 中使用 Chrome 调试器,但最好单独使用 Chrome 并查看控制台显示的内容。我会查看它,看看它是否比 Chrome 调试器提供了更好的指示。

标签: angular asp.net-core


【解决方案1】:

一个 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();
            });

        });

然后(也在 startup.cs 中):

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

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

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

感谢所有的cmets。他们让我不停地探索和尝试我不会想到的新事物(比如使用 IE)。

【讨论】:

    【解决方案2】:

    对于那些关心或像我一样不喜欢拥有完全宽松的 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")
    });
    

    我花了比它应该做的更多的时间来解决这个问题,所以如果它为其他人节省了一些时间,这篇文章是值得的:)

    【讨论】:

      【解决方案3】:

      您想使用application/jsoncontent-type,但将正文作为字符串发送:let _body = JSON.stringify(newComment);!!

      应该是:const _body = newComment;

      【讨论】:

      • 感谢您的回复,不幸的是,这没有用。来自 Angular2 调试器的相同错误(我正在使用 VS Code)和来自 API 调试器的相同响应(使用 VS2015)。唯一的区别是当我用 POSTMAN 拦截它时,它有一个额外的标头:Content-Type,其值为“application/x-www-form-urlencoded”。我相信 json.stringify 是正确的。 developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
      • 是的,如果你不是,角度会做到这一点。我的错。请查看浏览器开发工具 Angular 发送的内容。
      • 谢谢,不用担心。开发工具显示与 POSTMAN 相同的内容,基本上是一个空的 OPTION 正在发送。但这是个好主意,我将继续使用开发工具的屏幕截图编辑我的问题。
      猜你喜欢
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      • 2017-11-02
      • 2016-08-02
      • 2018-10-16
      • 1970-01-01
      • 1970-01-01
      • 2018-07-04
      相关资源
      最近更新 更多