简体   繁体   English

使用AngularJS发送HTTP请求到另一个域

[英]send HTTP request using AngularJS to another domain

I've been developing an API using django-rest-framework. 我一直在使用django-rest-framework开发API。

However, when i run virtual web server on localhost and try and send a request to api i get this error 但是,当我在本地主机上运行虚拟Web服务器并尝试向api发送请求时,出现此错误

XMLHttpRequest cannot load http://127.0.0.1:8000/users?format=json. No ' Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.

After a quick search i realized, that the problem is that i send request to a different domain ( different port in my situation ) and i can fix it by installing some new app. 经过快速搜索后,我意识到问题是我将请求发送到其他域(在我的情况下为其他端口),并且可以通过安装一些新应用程序来解决该问题。 However, i don't want to do it in django, but rather by edditing the way i make a request. 但是,我不想在django中这样做,而是通过编辑我发出请求的方式。 That's how i do it now: 我现在就是这样的:

Geonix.controller('mainController', function($scope, $http) {
          var config = { headers: {'Content-Type': 'application/json; charset=utf-8'}};
            $http.get('http://127.0.0.1:8000/users?format=json', config).success(function(data) {
                $scope.users = data;
            });
        });

Is there a way to get a right response without changing anything in back-end ? 有没有办法在不更改后端的情况下获得正确的响应? Note, that on actual server api and web page will be running on different ports as well, thus the problem will stay. 请注意,实际服务器上的api和网页也将在不同的端口上运行,因此问题仍然存在。

您应该使用django-cors或可以使用JSONP,但它仅接受get请求。

As others said, you should really look into using django-cors-middleware . 正如其他人所说,您应该真正考虑使用django-cors-middleware

If you have proper Auth methods, or the API is supposed to be public, you can go ahead and set CORS_ORIGIN_ALLOW_ALL = True on your settings.py for a super quick solution. 如果您拥有正确的Auth方法,或者应该公开使用该API,则可以继续在CORS_ORIGIN_ALLOW_ALL = True上设置CORS_ORIGIN_ALLOW_ALL = True ,以获取超快速解决方案。 I'm afraid there is not much else you can do beyond that. 恐怕除此之外您无能为力。

I once got around CORS by loading some routes in <img> tags, but it was a SUPER hacky approach for a very specific proof of concept I had to get running ASAP, when I had little control over the server. 我曾经通过在<img>标签中加载一些路由来避开CORS,但这是一种超级hacky的方法,用于在无法控制服务器的情况下必须尽快运行的非常具体的概念证明。 In that case, I only had to touch the routes for the server to do certain actions, and it was a Node.js server. 在那种情况下,我只需要触摸服务器的路由即可执行某些操作,它就是一台Node.js服务器。 I DO NOT recommend you try to hack around CORS, specially considering how easy it is to use django-cors-middleware. 建议您尝试绕过CORS,特别是考虑到使用django-cors-middleware多么容易。

As an added note django-cors-headers is no longer maintained. 作为补充,django-cors-headers不再维护。 You will need to use django-cors-middleware if your Django installation is version 1.10 or above. 如果您的Django安装版本为1.10或更高版本,则需要使用django-cors-middleware。

Angular is performing a pre-flight OPTIONS request on your Django app, but CORS is not enabled on Django. Angular正在您的Django应用上执行飞行前OPTIONS请求,但未在Django上启用CORS。 If you're able to activate CORS in Django you'll save yourself a lot of trouble. 如果您能够在Django中激活CORS,则可以省去很多麻烦。

Another option is to use JSONP, again a configuration change you would have to make in Django. 另一个选择是使用JSONP,这也是您必须在Django中进行的配置更改。

But the question is specifically about making the request without modifying Django. 但是问题特别是关于在不修改Django的情况下发出请求。

In that case, pre-flight is enabled because your content type is "application/json". 在这种情况下,由于您的内容类型为“ application / json”,因此启用了预检。 If you change it to "text/plain" Angular will skip the pre-flight and make the call. 如果将其更改为“文本/纯文本”,Angular将跳过预检并拨打电话。

Since the resulting data will be plain text, you can convert it to an object with JSON.parse() : 由于结果数据将是纯文本,因此您可以使用JSON.parse()将其转换为对象:

var config = { headers: {'Content-Type': 'text/plain; charset=utf-8'}};
$http.get('http://127.0.0.1:8000/users?format=json', config).success(function(data) {
  $scope.users = JSON.parse(data);
});

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

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