繁体   English   中英

来自AngularJS的Django CORS API

[英]Django CORS API from AngularJS

我已经在Django中使用“django-cors”启用了CORS:

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

按照此处的安装步骤后,我设置了以下内容:

CORS_ORIGIN_ALLOW_ALL = False

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

django应用程序在http:// locahost:3000上运行

我的前端是一个Angular应用程序,它运行在“http:/ localhost:8000”上,我已经完成了以下更改以与django应用程序进行通信。

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

[为资源API使用Restangular]

当我调用GET API时,会发生“OPTIONS”飞行前调用,并且出现以下错误:

XMLHttpRequest无法加载http:// localhost:3000 / users 凭据标志为“true”,但“Access-Control-Allow-Credentials”标头为“”。 允许凭据必须为“true”。 因此不允许来源' http:// localhost:8000 '访问。

查看文档,我了解到我需要设置服务器期望作为调用的一部分的某些标头。 所以,我添加了以下内容:RestangularProvider.setDefaultHeaders({“x-requested-with”:'XMLHttpRequest'});

但是,在进行此更改时,我收到另一个错误,我无法解决: XMLHttpRequest无法加载http:// localhost:3000 / users 预检的响应无效(重定向)

注意:请求/响应标头如下:

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

我终于设法解决了这个问题。 问题是由于API命名不正确。

我的同事将API命名如下:

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

当我打电话给“/ users”时,由于django的APPEND_SLASH设置,它正在进行永久重定向到“/ users /”。 这是django文档中关于APPEND_SLASH的内容

设置为True时,如果请求URL与URLconf中的任何模式都不匹配,并且不以斜杠结尾,则会向相同的URL发出HTTP重定向,并附加斜杠。 请注意,重定向可能导致POST请求中提交的任何数据丢失。

APPEND_SLASH设置仅在安装了CommonMiddleware使用。

当然,解决此问题的最简单(也是最好)的方法是通过删除斜杠来更新API URL,即

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

然后它将直接匹配URL,并且不会发出重定向。

但是,如果有人真的想在API中保留尾部斜杠,那么你仍然可以通过在AngularJS中添加以下代码来使其工作:

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

但是不建议使用上述内容,但是由于它来自我的实验,所以无论如何我都会分享它。

我在https://github.com/ottoyiu/django-cors-headers/blob/1e7bf86310e54cf2520c1b197d4e54bf80004df3/corsheaders/middleware.py中挖掘并发现可以使用

CORS_ALLOW_CREDENTIALS = True

在django settings.py中

这会将Access-Control-Allow-Credentials响应标头设置为True

我现在看到它甚至记录在案: https//github.com/ottoyiu/django-cors-headers

这解决了我

对于它的价值,似乎django-cors文档仅在django设置中使用主机名(而不是完整的URL),例如:

Example:

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


Default:

    CORS_ORIGIN_WHITELIST = ()

也许你可以尝试一个简单的东西,比如localhost ,然后尝试,如果有效,然后添加端口号并检查它是否仍然有效?

这个CORS创建问题就好像你设置了$httpProvider.defaults.withCredentials = true; 在你的角应用程序中。 我尝试了许多次解决方案,但经过长时间的搜索,这是我的解决方案,我相信它的工作对你而言

只需在Django apache配置文件中添加此代码,它可能是httpd.conf文件(通常位于* .conf文件中,例如httpd.conf或apache.conf),或者在.htaccess中。 然后只需添加此代码

<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> 

或者如果它们是内置代码,则在该文件中找到您的文件夹目录,并且只在其中找到此代码

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

并且您还需要使用以下更改角度应用配置

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