Плохой запрос 400 - Django REST Framework

У меня есть свой api в Django и Django REST framework (DRF).

Вот мой файл настроек:

DEBUG = False

ALLOWED_HOSTS = ['http://localhost:3000', 'http://127.0.0.1:3000']



# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'corsheaders',
    'MyApp.apps.MyappConfig',
]


REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSESS': 'rest_framework.permissions.AllowAny',
}

# React's Port : 3000
CORS_ORIGIN_WHITELIST = [
    'http://localhost:3000', 
    'http://127.0.0.1:3000',
]

CORS_ORIGIN_ALLOW_ALL = True

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    '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',
    'corsheaders.middleware.CorsMiddleware',
]

Я получаю ошибку Bad Request (400) Error:

Я проверил вкладку сети в Chrome, вот что я получил:

Request URL: http://localhost:8000/api/list
Request Method: GET
Status Code: 400 Bad Request
Remote Address: 127.0.0.1:8000
Referrer Policy: strict-origin-when-cross-origin
Connection: close
Content-Type: text/html
Date: Wed, 11 Aug 2021 13:05:24 GMT
Server: WSGIServer/0.2 CPython/3.8.1
X-Content-Type-Options: nosniff
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
Host: localhost:8000
sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"
sec-ch-ua-mobile: ?1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Mobile Safari/537.36

В React я получаю:

Access to XMLHttpRequest at 'http://localhost:8000/api/list/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

В чем проблема, в чем причина этой ошибки? API работает, и раньше у меня не было этой ошибки.

Добавьте csrf_token к вашему запросу в соответствии с защитой django от подделки межсайтовых запросов link

Перемещено в 'corsheaders.middleware.CorsMiddleware' под 'django.contrib.sessions.middleware.SessionMiddleware',

MIDDLEWARE = [
    .....
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    ......
]

если у вас есть специфический заголовок запроса, вы должны написать под CORS_ALLOW_HEADERS.

CORS_ALLOW_HEADERS = (
        'x-requested-with',
        'content-type',
        'accept',
        'origin',
)

Как в документации здесь https://github.com/adamchainz/django-cors-headers#setup

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

corsheaders.middleware.CorsMiddleware должен быть как можно выше CommonMiddleware

Не уверен, в чем ваша настоящая проблема, но я вижу две проблемы:

  • ALLOWED_HOSTS должен быть просто список имен хостов (или ips), без портов или схем. Django разрешил хосты с номером порта

    .
  • Из CorsMiddleware readme:

    CorsMiddleware должен быть размещен как можно выше, особенно перед любым промежуточным ПО, которое может генерировать ответы, таким как CommonMiddleware от Django или WhiteNoiseMiddleware от Whitenoise. Если оно не находится раньше, оно не сможет добавить CORS-заголовки к этим ответам.

    .

    Также, если вы используете CORS_REPLACE_HTTPS_REFERER, он должен быть размещен перед Django's CsrfViewMiddleware (см. подробнее ниже).

    .
Вернуться на верх