【问题标题】:AngularJS: POST Data to External REST APIAngularJS:将数据发布到外部 REST API
【发布时间】:2013-06-21 18:28:22
【问题描述】:

我有一个基本的 AngularJS 服务设置,如下所示:

app.factory('User', function($resource) {
return $resource('http://api.mysite.com/user/:action:id/:attr', {}, {
    history: {
        method: 'GET',
        params: {
            attr: 'history'
        }
    },
    update: {
        method: 'POST',
        params: {
            name: 'test'
        }
    }
});
});

我是这样使用它的:

User.history({id: 'testID'}, function(data) {
    console.log('got history');
    console.log(data);
});
User.update({id: 'me'}, function(data) {
    console.log('updated');
    console.log(data);
});

问题一: User.update() 尽管将方法设置为 POST,但仍将 OPTIONS 作为请求方法发送。

虽然 Chrome 开发工具报告请求标头 Access-Control-Request-Method:POST 也已发送(不确定这是否意味着什么)。

问题二:尽管在 API 代码中设置了这些标头,但我一直收到 CORS 错误:

header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Methods: PUT, GET, POST, DELETE, OPTIONS");

这个问题只有在发出非 GET 请求时才会出现。

处理此问题的正确方法是什么?我也研究过 JSONP,但由于这是一个 RESTful api,我不确定如何仅通过 GET 支持来解决问题。

【问题讨论】:

    标签: javascript api angularjs cross-domain cors


    【解决方案1】:

    你的两个问题实际上是一个问题。 OPTIONS 请求是 CORS 过程的一部分。对于 POST 请求,浏览器首先发送一个 OPTIONS 调用,如果可以执行,服务器会做出响应。

    如果 OPTIONS 请求失败,Angular / Chrome 会在控制台中显示原因。例如:

    OPTIONS https://*** Request header field Content-Type is not allowed by Access-Control-Allow-Headers. angular.min.js:106
    
    XMLHttpRequest cannot load https://***. Request header field Content-Type is not allowed by Access-Control-Allow-Headers. 
    

    您可能还必须在服务器上设置 Access-Control-Allow 标头:

    header('Access-Control-Allow-Headers: Content-Type, x-xsrf-token')
    

    x-xrsf-token 用于 angular' 以防止 CSRF。您可能需要添加更多标头,具体取决于您从客户端发送的内容。

    这是一个非常好的 CORS 指南:https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS

    【讨论】:

    • 浏览器发送 OPTIONS 请求然后 POST 请求是我的问题所在。服务器未设置为响应初始选项。不过,我不需要对 x-xsrf-token 做任何事情。使用此处的代码处理所有必要的标头:stackoverflow.com/questions/13293157/…
    • 这正是我的问题。谢谢。如果您使用 node/express,请按照此处的“启用飞行前”说明让 cors 工作:github.com/troygoode/node-cors
    【解决方案2】:

    在 AngularJS 中,要使 CORS 正常工作,您还必须覆盖 angular httpProvider 的默认设置:

    var myApp = angular.module('myApp', [
        'myAppApiService']);
    
    myApp.config(['$httpProvider', function($httpProvider) {
            $httpProvider.defaults.useXDomain = true;
            delete $httpProvider.defaults.headers.common['X-Requested-With'];
        }
    ]);
    

    仅将 useXDomain 设置为 true 是不够的。 AJAX 请求也是 使用 X-Requested-With 标头发送,这表明它们是 阿贾克斯。删除标头是必要的,因此服务器不会拒绝 传入的请求。

    注意:答案仅适用于 AngularJS 1.2 之前的旧版本。使用 1.2 及更高版本,您无需执行任何操作即可启用 CORS。

    【讨论】:

    • 这实际上没有必要,因为我可以访问 api 服务器并添加了header('Access-Control-Allow-Headers: X-Requested-With');,我认为它可以解决您所说的问题。
    • 好提示。我不知道设置允许标头标头。谢谢。
    • 也许您必须使用旧的 Angular 版本执行此操作,但我知道在 Angular 1.2.x 中,您不需要这样做。遵循@Narretz 的回答对我有用。
    • @TorstenEngelbrecht useXDomain 是被拒绝的拉取请求中的一个选项,从未存在,执行 useXDomain = true 将完成 nothing
    • @BenjaminGruenbaum 没有意识到这一点。我想知道为什么这次没有它就无法工作。无论如何,这个答案在 Angular 方面已经很老了,所以它很可能已经过时了。从那时起我就没有使用 CORS,到目前为止,我再也没有接触过那个区域。
    【解决方案3】:

    最好在服务器上解决这个问题。在 apache 上,您可以在 .htaccess 文件中像这样解决它。这是角度发展的痛苦来源,也可以用角度解决,但它可能不是最好的方法。

    Header set Access-Control-Allow-Origin "*"
    Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
    Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-17
      • 1970-01-01
      • 1970-01-01
      • 2016-08-19
      • 2019-01-25
      • 2020-12-07
      相关资源
      最近更新 更多