[英]CORS issue with Django and React hosted on same server
我在同一台服務器上遇到了我的Django Rest Framework和React應用程序的CORS問題。 我正在運行Vagrant,安裝了Ubuntu 18和NGINX(我假設這個問題將轉換為DigitalOcean)如果我提供的信息太多,我會提前道歉。 DRF正在使用Supervisor,Gunicorn在端口8000上。我使用create-react-app創建了我的React應用程序。 然后我使用npm run build
來創建靜態文件。
NGINX設置:
反應Conf
server {
listen 8080;
server_name sandbox.dev;
root /var/sites/sandbox/frontend/build;
index index.html;
client_max_body_size 4G;
location / {
try_files $uri $uri/ /index.html;
}
Django Conf
upstream sandbox_server {
server unix:/var/tmp/gunicorn_sanbox.sock fail_timeout=0;
}
server {
listen 8000;
server_name api.sandbox.dev;
...
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
if (!-f $request_filename) {
proxy_pass http://sandbox_server;
break;
}
Django設置:
INSTALLED_APPS = [
...
'rest_framework',
'corsheaders',
'myapp',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
...
]
我試過以下沒有運氣
CORS_ORIGIN_ALLOW_ALL = True
和
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = ('192.168.19.76:8080','localhost:8080',)
React App.js
...
fetch("http://localhost:8000/api/v1/token-auth/", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({"email":"test@user.com", "password":"testuser"}),
})
因此,要說明明顯的CORS是正確的,因為Origin是localhost:8080,它是一個不同的端口,因此它將其視為交叉原點。 我嘗試過cors origin允許的不同設置,但每次都是同樣的問題。 顯然我做錯了什么,但我看不出來。
我的想法是
選項1
代理傳遞使用django nginx conf文件並取消了反應nginx conf文件,但我不知道在生產中可能導致的影響或者這是一個好主意。 有沒有更好的辦法?
location /api {
proxy_set_header X-Forwarded_for $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://sandbox_server;
最后確定我的想法和我的問題。 在為CORS嘗試不同的Django選項后,我仍然收到CORS錯誤。 為什么,是我的NGINX配置文件導致它或其他什么? 我期待在DigitalOcean中看到這個嗎?
更新1
我忘了添加錯誤。 這是CORS錯誤
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/api/v1/token-auth/. (Reason: CORS request did not succeed).
對於那些想要了解網絡選項卡輸出的人
Host localhost:8000
Origin http://192.168.19.76:8080
Pragma no-cache
Referer http://192.168.19.76:8080/
更新2我使用curl測試,一切都按預期返回,所以我知道DRF正在正常工作。
curl --data "email=test@user.com&password=testuser" http://localhost:8000/api/v1/token-auth/
最終更新
感謝paulsm4的所有幫助和簡單的超棒。
所以,我確實放棄了django-cors-headers並推出了自己的。 為了回答paulsm4的問題,我沒有add_header 'Access-Control-Allow-Origin' '*';
在NGINX文件中,雖然我確實考慮讓NGINX處理CORS vs Django,但從未走得那么遠。 @ paulsm4,這是我正在談論的proxy_pass。 關鍵是將這段代碼添加到NGINX中,以便與我的中間件一起使用反應部分。
location /api {
proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://sandbox_server;
上面的代碼本身有效,但它不允許我將任何傳入的URL列入白名單。 創建我自己的中間件允許我白名單。 我不知道為什么django-cors-headers甚至django-cors-middleware都不適合我。 奇怪的是,除了我詢問的CORS錯誤之外,fetch從來沒有讓這兩個包獲得響應頭和任何類型的錯誤。 使用我編寫的中間件,fetch能夠完全進行調用,並返回一些響應頭,無論它是成功還是失敗。
為了將來參考,我可能會重新訪問NGINX並允許它處理CORS。 這是NGINX上的一個很好的鏈接CORS
注意
澄清; 除了Django已經包含的唯一中間件是cors中間件。 Django和React都駐留在同一台服務器上,但具有不同的端口。
Django settings.py
INSTALLED_APPS = [
...
# Third Party
'rest_framework',
'corsheaders',
# My Apps
'account',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
...
'django.middleware.csrf.CsrfViewMiddleware',
'corsheaders.middleware.CorsPostCsrfMiddleware',
...
]
CORS_ORIGIN_WHITELIST = (
'null',
'192.168.19.76:8080',
'localhost:8080',
'app.sandbox.com:8080'
)
React App.js
fetch("http://localhost:8000/api/v1/token-auth/", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
"email": "test@user.com",
"password": "testuser"
}),
})
所以我在這里結束了。 它是django-cors-headers無效或者可能是NGINX。
我們一直在交換意見; 這是我目前的理解:
問題 :你有一個Django后端API(在端口8080上)和一個React前端(在端口8000上)。 兩者目前都在localhost上運行,但最終將駐留在DigitalOcean上。 React客戶端正在獲取Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/api/v1/token-auth/. (Reason: CORS request did not succeed).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/api/v1/token-auth/. (Reason: CORS request did not succeed).
您需要配置CORS。
您捕獲的HTTP流量中的請求標頭清楚地表明這還沒有發生。
一些相關鏈接包括:
建議下一步:
如果您還沒有,請安裝並配置django-cors-headers
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.