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