【问题标题】:AngularJS: Cannot send POST request with appropiate CORS headersAngularJS:无法发送带有适当 CORS 标头的 POST 请求
【发布时间】:2014-07-27 19:29:46
【问题描述】:

我正在使用 AngularJS 创建一个网络应用程序。为了测试它,我在 NodeJS 服务器 中运行应用程序,使用 angular-seed template

在这个应用程序中,我需要通过 POST 请求向另一个主机发送 JSON 消息,并获得响应,因此,我使用的是 CORS

我的请求是通过实现一个使用AngularJS http service 的服务来完成的(我需要$http 提供的抽象级别。所以,我不使用$resource)。

这里,我的代码。请注意我修改了 $httpProvider 以告诉 AngularJS 发送带有适当 CORS 标头的请求

angular.module('myapp.services', []).

  // Enable AngularJS to send its requests with the appropriate CORS headers
  // globally for the whole app:
  config(['$httpProvider', function($httpProvider) {
          $httpProvider.defaults.useXDomain = true;

          /**
           * Just setting useXDomain to true is not enough. AJAX request are also
           * send with the X-Requested-With header, which indicate them as being
           * AJAX. Removing the header is necessary, so the server is not
           * rejecting the incoming request.
           **/
          delete $httpProvider.defaults.headers.common['X-Requested-With'];
      }
  ]).

  factory('myService', function($http) {
    return {
      getResponse: function() {
        var exampleCommand = JSON.stringify({"foo": "bar"});

        // This really doesn't make a difference
        /*
        var config = {headers: {
            'Access-Control-Allow-Origin':'*',
            'Access-Control-Allow-Headers': 'Content-Type, Content-Length, Accept',
            'Content-Type': 'application/json'
          }
        };
        */

        //return $http.post(REMOTE_HOST, exampleCommand, config).
        return $http.post(REMOTE_HOST, exampleCommand).
          success(function(data, status, headers, config) {
              console.log(data);
              return data;
          }).
          error(function (data, status, headers, config) {
            return {'error': status};
          });
      }
    }
  });

问题是我无法让它工作。我总是收到这个错误信息

跨域请求被阻止:同源策略不允许读取 REMOTE_HOST 的远程资源。这可以通过移动 资源到同一个域或启用 CORS。

但如果我像这样进行简单的 jQuery AJAX 调用:

$.ajax(REMOTE_HOST,
{
    dataType: "json",
    type: "POST",
    data: exampleCommand,
    success: function(data) { console.log(data); },
    error: function(request, textStatus, errorThrown) { console.log("error " + textStatus + ": " + errorThrown);}
 });

效果很好。

所以,我的问题:

- 如何在 NodeJS 下运行的 AngularJS 中允许跨站点请求?

更新:感谢 Dayan Moreno Leon 的回复。

我的问题是我需要add cors support to my server。我使用 NodeJS http-server 进行开发,使用 lighttpd 进行生产。

- 为什么简单的 jQuery POST 请求有效,而 AngularJS POST 请求无效?

我猜 jQuery AJAX 请求默认是cross-domain。还不确定。

在此先感谢

【问题讨论】:

  • 很抱歉评论过于简单,但您不能只使用 JSONP 吗?
  • @Chris JSONP 的问题在于你需要为它实现一个特定的逻辑,这意味着你必须告诉你的服务器构建一个 js 响应并将响应包装在一个回调函数调用中,这使得它非常特定于 jsonp,因此您将无法在非 jsonp 调用中重用它,此外它仅限于 json,除非您实现自己的响应回调解析器函数。使用 cors 在服务器和客户端都更加一致和干净,起初可能看起来很痛苦,但在共享资源时会为您节省大量时间和精力
  • Angular 中没有 useXDomain 这样的东西。它从未成为 Angular 代码。 github.com/angular/angular.js/issues/2956

标签: javascript jquery node.js angularjs cors


【解决方案1】:

CORS 不在客户端处理,但在服务器中,您需要在您的 Angular 应用程序尝试 POST 的 nodejs 应用程序上允许 CORS。如果你正在使用 express,你可以尝试使用 cors 模块

https://www.npmjs.org/package/cors

其他需要检查 options 方法并返回 200 作为响应的地方

http://en.wikipedia.org/wiki/Cross-origin_resource_sharing

【讨论】:

  • 我没有使用快递。那么,我是否需要事先发送一个 OPTIONS 请求,获取 200 状态响应,然后发送 POST 请求?因为我觉得高级的$resource服务是自动做的,但是这里不能用。
  • 不,你不需要做任何事情,这一切都由浏览器处理,无论来源如何,你的客户端代码都保持不变,POST、PUT 和 DELETE 是复杂的请求,所以浏览器首先发出一个选项请求,当它收到继续 (200) 时,它会发送实际请求,但要使其正常工作,您的服务器还需要能够响应复杂的请求,请查看此帖子 annasob.wordpress.com/2012/01/11/…
  • 好的。我在浏览器控制台中看到了 OPTIONS 请求。对不起,我读得太快了。我需要修改服务器。但我真的在使用 Node http-server 应用程序 (github.com/nodeapps/http-server)。我不知道如何配置它。也许我可以换成 lighttpd(生产服务器)
  • 还没有工作。但我想我已经接近了。我更新了问题
  • 您查看了我在上一条评论中链接的帖子吗?
【解决方案2】:

为什么简单的 jQuery POST 请求有效,而 AngularJS POST 请求无效?

jQuery 使用 simple requests 而 AngularJS 使用 preflighted requests

在您的角度代码中,您可以将集合 Content-Type 添加到 application/x-www-form-urlencoded 并使用 $.param 对您的数据进行编码

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-24
    • 1970-01-01
    • 2013-03-08
    • 1970-01-01
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多