React+Django应用CORS Header配置异常问题求助
问题描述
在React与Django集成的项目中,已在settings.py中设置CORS_ORIGIN_ALLOW_ALL = True,且已安装corsheaders应用,但前端从http://localhost:3000请求API时仍触发CORS策略错误:
Access to XMLHttpRequest at 'https://backend.com/api/v1/Category' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.
当前Django配置(settings.py)
INSTALLED_APPS = [ ..., 'corsheaders', ] MIDDLEWARE = [ ...., 'corsheaders.middleware.CorsMiddleware', ] TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'frontEnd/build'), os.path.join(BASE_DIR, 'templates'), ], 'DIRS': [os.path.join(BASE_DIR, 'templates'), # os.path.join(BASE_DIR, 'venv/lib/site-packages/django/contrib/admin/templates') ], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], 'libraries': { 'staticfiles': 'django.templatetags.static', }, }, }, ] STATIC_URL = '/static/' STATICFILES_DIRS = [os.path.join(BASE_DIR, 'frontEnd/build/static'), ] STATIC_ROOT = os.path.join(BASE_DIR, 'static') MEDIA_URL = '/media/' MEDIA_ROOT = BASE_DIR / 'media/' CKEDITOR_UPLOAD_PATH = 'ck/' CKEDITOR_CONFIGS = { 'default': { 'toolbar': 'full' }, } CORS_ALLOW_CREDENTIALS = True CORS_ORIGIN_ALLOW_ALL = True
前端Axios请求代码
import axios from 'axios' import { readCookie } from 'utils/readCookie' const isProduction = process.env.NODE_ENV === 'production' const csrfToken = readCookie('csrftoken') /** to log in to server using token in all requests */ const token = process.env.REACT_APP_SECRET_KEY const CancelToken = axios.CancelToken const source = CancelToken.source() export const request = axios.create({ baseURL: 'https://backend.com/api/v1', headers: { Authorization: token ? `Token ${token}` : '', 'X-CSRFToken': isProduction ? csrfToken : null, }, cancelToken: source.token, })
解决方案
1. 配置允许Authorization请求头
虽然CORS_ORIGIN_ALLOW_ALL = True允许了所有跨域源,但django-corsheaders默认的允许请求头列表不包含Authorization,需要手动添加配置:
在settings.py末尾添加以下代码:
# 明确指定允许的请求头,包含Authorization和X-CSRFToken CORS_ALLOW_HEADERS = [ 'accept', 'accept-encoding', 'authorization', 'content-type', 'dnt', 'origin', 'user-agent', 'x-csrftoken', 'x-requested-with', ]
如果是开发环境图省事,也可以直接允许所有请求头(生产环境不推荐):
CORS_ALLOW_ALL_HEADERS = True
2. 检查中间件顺序
确保corsheaders.middleware.CorsMiddleware在MIDDLEWARE列表的最前面,它需要在其他处理请求的中间件之前执行,否则CORS头不会被正确添加。修改后的MIDDLEWARE示例:
MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 其他中间件... ]
3. 验证修改
保存settings.py后重启Django服务,前端重新发起请求,CORS错误即可解决。
内容的提问来源于stack exchange,提问作者fatemeh zamanipour

