Ошибка CORS при использовании React native web с Nginx + Django
Я столкнулся с ошибкой CORS на сервере EC2 Django + Nginx. Понятия не имею, почему это никогда не работает.
Ошибка:
Access to fetch at 'https://serveraddress/api/v1/user' from origin 'http://localhost:19006' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Как я просил
fetch(`https://${env.apiUrl}/api/v1/user`, {
method: "GET",
mode: "cors",
withCredentials: true,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers":
"Origin, X-Requested-With, Content-Type, Accept",
"Access-Control-Allow-Methods":"GET,PUT,POST,DELETE,OPTIONS",
"Access-Control-Allow-Credentials":'true',
Authorization: await getToken(),
},
Также пробовал использовать Authorization header или request get, post request auth is not requried, но ни один из них не сработал. Плюс, пробовал использовать axios, xmlhttprequest и ни один из них не сработал...
Ниже приведены настройки для Nginx + Django
Nginx Settings
location / {
proxy_hide_header Access-Control-Allow-Origin;
add_header Access-Control-Allow-Origin '*';
add_header Access-Control-Allow-Credentials true always;
proxy_pass http://web/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
Django Settings
Все настройки для cors, включая django-cors-headers middleware, и поместите corsheaders.middleware.CorsMiddleware поверх него.
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
....
]
CORS_ORIGIN_ALLOW_ALL = True
ALLOWED_HOSTS = ['*']
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
]
CORS_ALLOW_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
]
CORS_ALLOWED_ORIGIN_REGEXES = [
r"^https://\w+\.domain\.com$",
]
CSRF_TRUSTED_ORIGINS = ['*']
CORS_ALLOWED_ORIGINS = ['*']
Также проверил сообщение preflight с помощью опций curl и получил < HTTP/1.1 200 OK.
curl --verbose --request OPTIONS 'https://serveraddress/api/v1/user/profile' --header 'Origin: https://localhost:19006' --header 'Access-Control-Request-Headers: Origin, Accept, Content-Type' --header 'Access-Control-Request-Method: GET'
Это работает на Android или iOS, но никогда не работает в Интернете.
Я обнаружил, что есть похожие проблемы с React, но их можно решить с помощью http-proxy-middleware или добавить прокси на package.json
.
https://create-react-app.dev/docs/proxying-api-requests-in-development/.
Но, похоже, я не могу установить прокси для react native web.
Наконец-то заработало! Это была проблема Nginx. Добавление следующих строк в расположение / помогло.
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET,PUT,POST,OPTIONS,HEAD,DELETE';
add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
if ($request_method = 'OPTIONS') {
return 204;
}