简体   繁体   English

来自AngularJS的Django CORS API

[英]Django CORS API from AngularJS

I have enabled CORS in Django, with "django-cors": 我已经在Django中使用“django-cors”启用了CORS:

https://github.com/ottoyiu/django-cors-headers https://github.com/ottoyiu/django-cors-headers

After following the installation steps here, I have set the following: 按照此处的安装步骤后,我设置了以下内容:

CORS_ORIGIN_ALLOW_ALL = False

CORS_ORIGIN_WHITELIST = (
    'http://localhost:8000'
)

The django app runs on http://locahost:3000 django应用程序在http:// locahost:3000上运行

My frontend is an Angular app, which runs on "http:/localhost:8000", and I have done the following changes to communicate with the django app. 我的前端是一个Angular应用程序,它运行在“http:/ localhost:8000”上,我已经完成了以下更改以与django应用程序进行通信。

RestangularProvider.setBaseUrl('http://localhost:3000/');

[Using Restangular for resource APIs] [为资源API使用Restangular]

When I call the GET API, the "OPTIONS" pre-flight call happens, and I get the following error: 当我调用GET API时,会发生“OPTIONS”飞行前调用,并且出现以下错误:

XMLHttpRequest cannot load http://localhost:3000/users . XMLHttpRequest无法加载http:// localhost:3000 / users Credentials flag is 'true', but the 'Access-Control-Allow-Credentials' header is ''. 凭据标志为“true”,但“Access-Control-Allow-Credentials”标头为“”。 It must be 'true' to allow credentials. 允许凭据必须为“true”。 Origin ' http://localhost:8000 ' is therefore not allowed access. 因此不允许来源' http:// localhost:8000 '访问。

Looking at the documentation, I understood that I needed to set certain headers which the server would expect as a part of the call. 查看文档,我了解到我需要设置服务器期望作为调用的一部分的某些标头。 So, I added the following: RestangularProvider.setDefaultHeaders({"x-requested-with" : 'XMLHttpRequest'}); 所以,我添加了以下内容:RestangularProvider.setDefaultHeaders({“x-requested-with”:'XMLHttpRequest'});

However, on making this change, I am getting another error, which I am unable to resolve: XMLHttpRequest cannot load http://localhost:3000/users . 但是,在进行此更改时,我收到另一个错误,我无法解决: XMLHttpRequest无法加载http:// localhost:3000 / users Response for preflight is invalid (redirect) 预检的响应无效(重定向)

Note: The request/response headers are as follows: 注意:请求/响应标头如下:

General:
Remote Address:127.0.0.1:3000
Request URL:http://localhost:3000/users
Request Method:OPTIONS
Status Code:301 MOVED PERMANENTLY

Response Headers
Access-Control-Allow-Headers:x-requested-with, content-type, accept, origin, authorization, x-csrftoken, user-agent, accept-encoding
Access-Control-Allow-Methods:GET, POST, PUT, PATCH, DELETE, OPTIONS
Access-Control-Allow-Origin:http://localhost:8000
Access-Control-Max-Age:86400
Content-Type:text/html; charset=utf-8
Date:Thu, 17 Dec 2015 11:10:16 GMT
Location:http://localhost:3000/users/
Server:WSGIServer/0.1 Python/2.7.10
X-Frame-Options:SAMEORIGIN

Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:accept, x-requested-with
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
Host:localhost:3000
Origin:http://localhost:8000
Pragma:no-cache
Referer:http://localhost:8000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36

I finally managed to resolve the problem. 我终于设法解决了这个问题。 The problem was because of improper API naming. 问题是由于API命名不正确。

My colleague had named the API as follows: 我的同事将API命名如下:

url(r'^users/', views.user_details)

And when I would call "/users", then because of django's APPEND_SLASH setting, it was doing a permanent redirect to "/users/". 当我打电话给“/ users”时,由于django的APPEND_SLASH设置,它正在进行永久重定向到“/ users /”。 Here's what the django documentation says about APPEND_SLASH : 这是django文档中关于APPEND_SLASH的内容

When set to True, if the request URL does not match any of the patterns in the URLconf and it doesn't end in a slash, an HTTP redirect is issued to the same URL with a slash appended. 设置为True时,如果请求URL与URLconf中的任何模式都不匹配,并且不以斜杠结尾,则会向相同的URL发出HTTP重定向,并附加斜杠。 Note that the redirect may cause any data submitted in a POST request to be lost. 请注意,重定向可能导致POST请求中提交的任何数据丢失。

The APPEND_SLASH setting is only used if CommonMiddleware is installed. APPEND_SLASH设置仅在安装了CommonMiddleware使用。

Of course, the simplest (and best) way of resolving this problem, is to update the API url by removing the slash, ie 当然,解决此问题的最简单(也是最好)的方法是通过删除斜杠来更新API URL,即

url(r'^users', views.user_details)

Then it would match the URL directly, and no redirect will be issued. 然后它将直接匹配URL,并且不会发出重定向。

However, in case someone really wants to keep the trailing slash in the API, then you can still make it work, by adding the following code in AngularJS: 但是,如果有人真的想在API中保留尾部斜杠,那么你仍然可以通过在AngularJS中添加以下代码来使其工作:

resourceProvider.defaults.stripTrailingSlashes = false;
RestangularProvider.setRequestSuffix('/'); 

The above is however not recommended, but since it came out of my experiments, I am sharing it anyways. 但是不建议使用上述内容,但是由于它来自我的实验,所以无论如何我都会分享它。

I dug around in https://github.com/ottoyiu/django-cors-headers/blob/1e7bf86310e54cf2520c1b197d4e54bf80004df3/corsheaders/middleware.py and found that one can use 我在https://github.com/ottoyiu/django-cors-headers/blob/1e7bf86310e54cf2520c1b197d4e54bf80004df3/corsheaders/middleware.py中挖掘并发现可以使用

CORS_ALLOW_CREDENTIALS = True

in django settings.py 在django settings.py中

this will set the Access-Control-Allow-Credentials response header to True 这会将Access-Control-Allow-Credentials响应标头设置为True

I now see it's even documented: https://github.com/ottoyiu/django-cors-headers 我现在看到它甚至记录在案: https//github.com/ottoyiu/django-cors-headers

That solved it for me 这解决了我

For what it worth, it seems the django-cors documentation only uses hostnames (and not the full URL) in the django settings, like: 对于它的价值,似乎django-cors文档仅在django设置中使用主机名(而不是完整的URL),例如:

Example:

    CORS_ORIGIN_WHITELIST = (
        'google.com',
        'hostname.example.com'
    )


Default:

    CORS_ORIGIN_WHITELIST = ()

Maybe you can try with a simple thing, like localhost , then try if if works, then add the port number and check if it still works ? 也许你可以尝试一个简单的东西,比如localhost ,然后尝试,如果有效,然后添加端口号并检查它是否仍然有效?

This CORS creating problems as if you set $httpProvider.defaults.withCredentials = true; 这个CORS创建问题就好像你设置了$httpProvider.defaults.withCredentials = true; in your angular app. 在你的角应用程序中。 i tried many times with many solution but after long search this is my solution for you and i am sure its work for you 我尝试了许多次解决方案,但经过长时间的搜索,这是我的解决方案,我相信它的工作对你而言

just add this code in your Django apache config file its may be httpd.conf file (usually located in a *.conf file, such as httpd.conf or apache.conf), or within a .htaccess. 只需在Django apache配置文件中添加此代码,它可能是httpd.conf文件(通常位于* .conf文件中,例如httpd.conf或apache.conf),或者在.htaccess中。 then just add this code 然后只需添加此代码

<IfModule mod_headers.c>
SetEnvIf Origin (.*) AccessControlAllowOrigin=$1
Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
Header set Access-Control-Allow-Credentials true
</IfModule> 

or if their is inbuilt code then find your folder directory in that file and only this code in it 或者如果它们是内置代码,则在该文件中找到您的文件夹目录,并且只在其中找到此代码

SetEnvIf Origin (.*) AccessControlAllowOrigin=$1
    Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    Header set Access-Control-Allow-Credentials true

and also you need to change angular app config with following 并且您还需要使用以下更改角度应用配置

angular.module('app', ['ngCookies'])
    .config([
   '$httpProvider',
   '$interpolateProvider',
   function($httpProvider, $interpolateProvider, $scope, $http) {
       $httpProvider.defaults.withCredentials = true;
       $httpProvider.defaults.xsrfCookieName = 'csrftoken';
       $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
   }]).
   run([
   '$http',
   '$cookies',
   function($http, $cookies) {
       $http.defaults.headers.post['X-CSRFToken'] = $cookies.csrftoken;
   }]);

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

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