来自 docker 上的 React 应用的 nginx/django 的 Cors 问题

Cors problem with nginx/django from react app on docker

我对 django 中的 cors 实现有疑问。 设置正确的 cors 值时遇到问题。 我的部署在 docker。 我部署了 3 个容器:

一切都在本地主机上。 我使用前端的 axios 来调用 get/post 请求。 (我调用 1338 端口然后我认为它被重定向到 8000 端口上的内部服务) 对于后端,我必须安装 django-cors-headers 包才能使用 CORS。 我想我设置正确。但是在某些情况下它不起作用。

在settings.py

INSTALLED_APPS = [
...
"corsheaders",
]
...
MIDDLEWARE = [
...
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
...
]

Nginx.conf 对于 nginx 图像:

upstream backend {
    server backend:8000;
}

server {

    listen 80;

    add_header Access-Control-Allow-Origin *;

    

    location / {

        proxy_pass http://backend;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host:1337;
        proxy_redirect off;
    }

    location /static/ {
        alias /home/app/web/staticfiles/;
    }
}

第一个场景

在settings.py

CORS_ALLOW_ALL_ORIGINS = True

没有 get/post 请求工作。获取消息:
不允许 CORS 多源

第二种情况
在settings.py

CORS_ALLOWED_ORIGINS = ["http://localhost:1337"]

适用于 get 请求,但不适用于 post 请求。

对于 post 个请求:

如果我不使用 nginx 作为后端,它就可以工作。

根据评论中的要求添加请求headers。

我不确定我还能在这里添加什么。所以我部署的项目在这里(如果你的机器上有 docker,它也很容易启动: https://gitlab.com/k.impolevicius/app-001

你好,问题似乎出在 axios.post 而不是 Django 或 nginx。

因为如果你从 drf browsable api 卷曲 post 或 post,它工作正常:

curl -X POST http://localhost:1337/Country/ \
  -H "Content-Type: application/json" \
  -d '{"name": "other"}'
{"id":6,"name":"other"}%

但是 React 应用生成这个 OPTIONS 请求:

app-001-backend-1   | [13/May/2022 05:56:20] "OPTIONS /Country/ HTTP/1.0" 200 0
app-001-nginx-1     | 192.168.240.1 - - [13/May/2022:05:56:20 +0000] "OPTIONS /Country/ HTTP/1.1" 200 0 "http://localhost:1338/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.4 Safari/605.1.15" "-"

我前段时间遇到过这个问题,我认为问题出在 header 上。 在 MDN 文档中,说明了 here that other than for the simple requests, we'll get preflighted requests with OPTIONS 方法。在您的案例中,我们需要发送 3 个主要 header 作为回应

Access-Control-Allow-Origin: http://localhost:1337
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: Content-Type

从外观上看,您已经配置了第一个 header,您也应该在网络选项卡中看到它,并且由于错误是关于缺少允许 header,您需要添加 Access-Control-Allow-Methods header 到你的 nginx 文件

add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';

在请求的 headers 上看到您的网络选项卡将在此处提供更多上下文,通常您应该在 [=] 中看到 Access-Control-Request-MethodAccess-Control-Request-Headers headers 15=] 请求。如果有一些 header 是您不允许的,请为此编写一个 nginx 规则。您可以查看 this solution 以获得更多参考