Проблема Cors с nginx/django из приложения react на docker
У меня вопрос о реализации cors в django. У меня проблема с установкой правильных значений cors. Мое развертывание происходит на docker. У меня развернуто 3 контейнера:
- backend: Django + DRF в качестве бэкенда (выставить 8000 порт)
- Nginx для сервера моего бэкенда (используйте открытый порт 8000 и установите его на 1338)
- frontend React app используется с nginx (используется порт 1337)
Все находится на localhost. Я использую axios из frontend для вызова get/post запросов. (Я звоню на 1338 порт, затем, я думаю, он перенаправляется на внутренний сервис на 8000 порт). Для бэкенда мне пришлось установить пакет django-cors-headers для работы с CORS. Я думаю, что установил его правильно. Но есть сценарии, где это не работает.
В settings.py
INSTALLED_APPS = [
...
"corsheaders",
]
...
MIDDLEWARE = [
...
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
...
]
Первый сценарий
В settings.py
CORS_ALLOW_ALL_ORIGINS = True
Не работают запросы get/post. Получение сообщения:
CORS Multiple Origin Not Allowed
Второй сценарий
.
В settings.py
CORS_ALLOWED_ORIGINS = ["http://localhost:1337"]
Работает с get-запросами, но не работает с post-запросами.
Для запросов на почту:
- опции с ошибкой: CORS Missing Allow Header
- пост с ошибкой: NS_ERROR_DOM_BAD_URI
Это работает, если я не использую nginx для бэкенда.
Я не уверен, что еще можно добавить сюда. Итак, мой развернутый проект находится здесь: https://gitlab.com/k.impolevicius/app-001
Добрый день, похоже, что проблема в axios.post а не в Django или nginx.
Потому что если вы делаете curl post или post из drf browsable api, он работает нормально:
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" "-"
Я столкнулся с этой проблемой некоторое время назад, и я думаю, что проблема заключается в заголовках. В документации MDN говорится здесь, что кроме простых запросов, мы будем получать префлайтинговые запросы с помощью метода OPTIONS. Есть 3 основных заголовка, которые мы должны отправить в ответ в вашем случае
Access-Control-Allow-Origin: http://localhost:1337
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: Content-Type
Судя по всему, вы настроили первый заголовок, и вы должны видеть его на вкладке network, а поскольку ошибка связана с отсутствием разрешающих заголовков, вам нужно добавить заголовок Access-Control-Allow-Methods
в ваш файл nginx
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
Просмотр вашей сетевой вкладки на запрашиваемых заголовках даст больше контекста, обычно вы должны видеть Access-Control-Request-Method и Access-Control-Request-Headers заголовки в запросе OPTIONS. Если есть некоторые заголовки, которые вы не разрешаете, пожалуйста, напишите правило nginx для них. Вы можете посмотреть это решение для получения дополнительной информации
