#python #reactjs #django #cors #django-cors-headers
#python #reactjs #джанго #корс #django-cors-headers
Вопрос:
Я запускаю локальную версию своего приложения react на localhost: 3000 и пытаюсь достичь конечных точек на сервере Django, размещенном на heroku
Ошибка, возникающая при каждом запросе axios: доступ к XMLHttpRequest заблокирован политикой CORS: заголовок ‘Access-Control-Allow-Origin’ отсутствует
Текущий settings.py для сервера Django:
ALLOWED_HOSTS=['*']
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'corsheaders',
'whitenoise.runserver_nostatic',
'django.contrib.staticfiles',
'accounts',
'blog',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
# Whitenoise
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
#'django.middleware.clickjacking.XFrameOptionsMiddleware',
# Machina
#'machina.apps.forum_permission.middleware.ForumPermissionMiddleware',
]
# CORS
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_CREDENTIALS = False
Поскольку я разрешаю всем источникам отправлять запросы, похоже, что этот тип проблемы CORS должен быть отключен. Я попытался удалить все другое промежуточное программное обеспечение, кроме CorsMiddleware, и это ничего не изменило.
На данный момент немного озадачен, потому что моя конфигурация кажется правильной в соответствии https://github.com/adamchainz/django-cors-headers
Вот пример вызова api из моего приложения react, который вызывает заголовок «no ‘Access-Control-Allow-Origin'»
function callCSRFApi(){
return axios.request({
method: 'GET',
url: 'http://example.com/csrf/',
});
}
Следует отметить, что я нажимаю конечные точки на сервере Django, даже если он не настроен как API django_rest.
Я также попытался установить пользовательское промежуточное программное обеспечение, которое всегда должно определять Access-Control-Allow-Origin, но все равно получил, что заголовок отсутствует:
class CorsMiddleware(object):
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
response = self.get_response(request)
if (request.method == "OPTIONS" and "HTTP_ACCESS_CONTROL_REQUEST_METHOD" in request.META):
response = http.HttpResponse()
response["Content-Length"] = "0"
response["Access-Control-Max-Age"] = 86400
response["Access-Control-Allow-Origin"] = "*"
response["Access-Control-Allow-Methods"] = "DELETE, GET, OPTIONS, PATCH, POST, PUT"
response["Access-Control-Allow-Headers"] = "accept, accept-encoding, authorization, content-type, dnt, origin, user-agent, x-csrftoken, x-requested-with"
return response
Я думаю, что проблема может быть в том, что у нас нет сервера Django, настроенного как приложение django_rest, или что у django есть логика, по которой к нему нельзя получить доступ с локального хоста.
Примечание:
- Я тестирую в окне инкогнито после прочтения, что у других возникли проблемы с кэшем
- Пробовали вернуться к более ранней версии django-cors-headers
- Пробовали без CORS_ALLOW_CREDENTIALS = False
- Запросы GET работали при запуске как сервера django, так и приложения react на разных портах localhost
- Python 3.7, Django 3.0.7, django-cors-заголовки 3.5.0, React 17.0.1, axios 0.21.0
Ответ №1:
Попробуйте установить CORS_ALLOW_CREDENTIALS = True
в настройках Django и { withCredentials: true }
в конфигурации axios.
Комментарии:
1.
function callCSRFApi(){ return axios.request({ method: 'GET', url: 'http://' hostURL '/csrf/', // TODO: Will need to change to Prod withCredentials: true, }); }
2. Я установил CORS_ALLOW_CREDENTIALS = True в settings.py так же хорошо, но получая тот же результат
3. Добавлен новый ответ.
Ответ №2:
У меня самого были некоторые проблемы с axios и CSRF, и мне нравится просто использовать собственный fetch-API. Этот код работает с Django и corsheaders:
export async function authenticateUser() {
const response = await fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': Cookies.get('csrftoken')
},
credentials: 'include',
});
return response.json()
}
Комментарии:
1. Ошибка, похоже, другая: [Доступ к выборке в ‘ example.com/csrf ‘ из источника ‘ localhost:3000 ‘ заблокирован политикой CORS: ответ на предполетный запрос не проходит проверку контроля доступа: перенаправление не разрешено для предполетного запроса]. Но запрос по-прежнему блокируется политикой CORS.
2. Вы также установили js-cookie и включили «X-CSRFToken»? Вам также понадобится файл cookie ‘csrftoken’ в вашем приложении (например, войдя на страницу администратора).
3. На данный момент я просто делаю запрос get, поэтому я не думаю, что мне нужен токен csrf (но поправьте меня, если я ошибаюсь).
4. Следует отметить, что выполнение перекрестных запросов между localhost: 3000 и localhost: 8000 работает, но когда я пытаюсь указать localhost: 3000 (local react app) на example.com (приложение prod django) Я начинаю получать ошибки CORS.
Ответ №3:
Попробуйте добавить белый список в свой settings.py
корс
CORS_ALLOWED_ORIGINS = [ ‘http://localhost:3000 ‘, ]