簡體   English   中英

與同一服務器上托管的Django和React的CORS問題

[英]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都駐留在同一台服務器上,但具有不同的端口。

  1. api.sandbox.com:8000是Django Rest Framework
  2. app.sandbox.com:8080是React靜態文件
  3. Django 2.0.2
  4. Python 3.6
  5. django-cors-headers 2.4.0
  6. Vagrant / VirtualBox Ubuntu 18.04
  7. NGINX

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM