2016-07-04 49 views
1

我正在開發一些與django網站aaa.com,它發送跨域ajax「GET」請求從bbb.com接收json數據,它也在django上運行,並且使用REST框架。在這一點上,一切工作都很好,加入crossDomain: true; withCredentials:true。當然,它可以在aaa.com的服務器端進行配置。
...-Allow-Credentials: true; ...-Allow-Origin: bbb.com跨域ajax選項錯誤403(Django)

主要問題出現在aaa.com試圖使PUT POST DELETE ajax請求時。 根據CORS文檔: [https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0],客戶端AJAX請求是正確的,並
...-Allow-Headers, ...-Allow-Methods

...-Request-Headers, ...-Request-Methods

匹配,從而該請求不是「簡單的」和第一全瀏覽器發送從預檢請求aaa.com向bbb.com詢問是否允許一些自定義標題和方法。

一切都還好但我仍然得到403錯誤。下面是請求/響應:

General: 
Request URL:http://bbb.com/api/someapipage/ 
Request Method:OPTIONS 
Status Code:403 Forbidden 
Remote Address:some ip:80 

Response Headers: 
Access-Control-Allow-Credentials:true 
Access-Control-Allow-Headers:accept, content-type, x-csrftoken, x-requested-with 
Access-Control-Allow-Methods:GET, POST, OPTIONS, HEAD, PUT, DELETE 
Access-Control-Allow-Origin:http://aaa.com 
Allow:GET, POST, HEAD, OPTIONS 
Connection:Keep-Alive 
Content-Language:en 
Content-Type:application/json 
Date:Mon, 04 Jul 2016 14:20:38 GMT 
Keep-Alive:timeout=5, max=100 
Server:gunicorn/19.6.0 
Transfer-Encoding:chunked 
Vary:Accept,Accept-Language,Cookie 
X-Frame-Options:SAMEORIGIN 

Request Headers: 
Accept:*/* 
Accept-Encoding:gzip, deflate, sdch 
Accept-Language:en-US,en;q=0.8,ru;q=0.6 
Access-Control-Request-Headers:accept, content-type, x-csrftoken 
Access-Control-Request-Method:POST 
Connection:keep-alive 
Host:aaa.com 
Origin:http://aaa.com 
Referer:http://aaa.com/ 
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36 

試圖解決這個問題,一週後,我意識到,服務器要因人而異:對預排期的請求,餅乾,因爲跨域飛行前請求不能包含餅乾這是不可能的在其標題中。

我開始找到了一些解決這個問題,並發現: https://code.djangoproject.com/ticket/13217

「啓用django.middleware.locale.LocaleMiddleware導致該Django的增加了一個‘有所不同:餅乾’。頭到每個效應初探」 因此,localMiddleware添加頭Vary:即使在飛行前選項響應

有很多推薦使用djang-cors-header來解決這些問題。但是使用這個包函數等於我在服務器端的設置。

我也發現漂亮包:django-dont-vary-on如果安裝了可以設置裝飾者關閉Vary:cookie,但在我的情況下,我需要關閉Vary:cookie只在OPTIONS響應中。

我對django有點新鮮感,實際上甚至無法想象在這種情況下該做什麼。我的每一步就像走在礦場上一樣。 有沒有解決方案或一些替代方案?

回答

1

您必須將您的客戶端的CORS白名單訪問服務器。

如果他們是跨域請求,如果使用除GET,HEAD或POST以外的方法,則該請求將變爲預檢。

此外,如果POST用於與內容類型發送請求數據以外的 比應用程序/ x-WWW窗體-urlencoded,多部分/形式數據,或者 文本/無格式,它成爲預檢。

它的服務器允許處理或拒絕跨域客戶端請求(默認)。

因此,如果您有權訪問服務器端應用程序,則可以執行以下操作獲取響應。

在服務器端

在你的服務器端和白名單您的客戶端域或IP(這也是特定端口的)

pip install django-cors-headers 

在settings.py安裝django-cors-headers,在你的INSTALLED_APPS添加它

INSTALLED_APPS = (
... 
    'corsheaders', 
... 
) 

添加corsheaders.middleware.CorsMiddleware在MIDDLEWARE_CLASSES

MIDDLEWARE_CLASSES = (
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.contrib.sessions.middleware.SessionMiddleware', 
    '**corsheaders.middleware.CorsMiddleware**', 
    'django.middleware.common.CommonMiddleware', 
.... 
) 

,並定義白名單CORS

CORS_ORIGIN_WHITELIST = (
    'aaa.com', 
) 

現在,當您在CORS白名單添加你的客戶,你現在可以做一個成功的Ajax請求。

+0

感謝您的回覆!只要我獲得訪問服務器端,我會嘗試你的解決方案 –

+0

這解決了我的問題!非常感謝! –

+0

我很高興它幫助:-) – kapilsdv