简体   繁体   English

AngularJS:POST数据到外部REST API

[英]AngularJS: POST Data to External REST API

I have a basic AngularJS service setup like so: 我有一个基本的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'
        }
    }
});
});

and I use it like this: 我这样使用它:

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);
});

Problem one: User.update(), despite having the method set to POST, keeps sending OPTIONS as the request method. 问题一: User.update(),尽管将方法设置为POST,仍然继续发送OPTIONS作为请求方法。

Though Chrome Dev tools reports the request header Access-Control-Request-Method:POST is sent as well (Not sure if that means anything). 虽然Chrome Dev工具报告了请求标头Access-Control-Request-Method:也会发送POST(不确定这是否意味着什么)。

Problem two: I keep getting an error with CORS, despite having these headers set in the API code: 问题二:尽管在API代码中设置了这些标头,我仍然在使用CORS时出错:

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

This problem only shows up though if making a non-GET request. 如果发出非GET请求,则只会出现此问题。

What's the proper way to be handling this? 处理这个问题的正确方法是什么? I've also looked into JSONP, but with this being a RESTful api, I'm not sure how to get around the problems with only GET support. 我也研究了JSONP,但是这是一个RESTful api,我不知道如何解决只有GET支持的问题。

Your two problems are actually one problem. 你的两个问题实际上是一个问题。 The OPTIONS request is part of the CORS process. OPTIONS请求是CORS过程的一部分。 For POST requests, the browser first sends an OPTIONS call, and the server responds if it is okay to execute it. 对于POST请求,浏览器首先发送OPTIONS调用,服务器响应是否可以执行它。

If the OPTIONS request fails, Angular / Chrome shows you the reason in the console. 如果OPTIONS请求失败,Angular / Chrome会在控制台中显示原因。 For example: 例如:

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. 

You probably have to set Access-Control-Allow Headers on the server, too: 您可能还必须在服务器上设置Access-Control-Allow Headers:

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

x-xrsf-token is for angular' to prevent CSRF. x-xrsf-token用于“防止CSRF”。 You may have to add more headers, depending on what you send from the client. 您可能需要添加更多标头,具体取决于您从客户端发送的内容。

Here is a very good guide on CORS: https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS 这是一篇关于CORS的非常好的指南: https//developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS

In AngularJS to make CORS working you also have to overwrite default settings of the angular httpProvider : 在AngularJS中,要使CORS正常工作,您还必须覆盖角度httpProvider默认设置:

var myApp = angular.module('myApp', [
    'myAppApiService']);

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

Just setting useXDomain to true is not enough. 仅将useXDomain设置为true是不够的。 AJAX request are also send with the X-Requested-With header, which indicate them as being AJAX. AJAX请求也与X-Requested-With标头一起发送,表明它们是AJAX。 Removing the header is necessary, so the server is not rejecting the incoming request. 删除标头是必要的,因此服务器不会拒绝传入的请求。

Note : Answer only works for older AngularJS version previous to 1.2. 注意 :答案仅适用于1.2之前的旧AngularJS版本。 With 1.2 and above you don't have to do do anything to enable CORS. 使用1.2及更高版本,您无需执行任何操作来启用CORS。

Better to solve this problem at the server. 最好在服务器上解决这个问题。 On apache you can solve it like this in a .htaccess file. 在apache上,您可以在.htaccess文件中解决此问题。 This is a source of pain for angular development and can be solved in angular as well but its probably not the best way to do it. 这是角度发展的痛苦来源,也可以角度解决,但它可能不是最好的方法。

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"

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

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