Django与Vue集成时django-cors-headers失效问题求助
我从前端(http://localhost:5173)访问Django REST Framework接口(http://localhost:8000/api/students)时,遇到CORS错误,数据无法正常传递,错误信息如下:
Access to fetch at 'http://localhost:8000/api/students' from origin 'http://localhost:5173' has been blocked by CORS policy: 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.
我尝试使用django-cors-headers并配置了各类相关设置,也试过自定义中间件,但都没有效果。以下是相关配置信息:
当前settings.py相关配置(部分已注释)
ALLOWED_HOSTS = ['*'] # 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', 'students' ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'project.middleware.CustomCorsMiddleware', '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', ] # clickjacking not compatible with corsheaders? CORS_ORIGIN_ALLOW_ALL = True # CORS_ALLOW_CREDENTIALS = True # CORS_ORIGIN_WHITELIST = [ # "http://localhost:8000", # "http://127.0.0.1:8000", # "http://localhost:5173", # "http://127.0.0.1:5173", # ] # CORS_ALLOW_HEADERS = ['*'] # # CSRF_TRUSTED_ORIGINS = [ # "http://localhost:8000", # "http://127.0.0.1:8000", # "http://localhost:5173", # "http://127.0.0.1:5173", # ]
尝试过的自定义中间件
class CustomCorsMiddleware: def __init__(self, get_response): self.get_response = get_response # One-time configuration and initialization. def __call__(self, request): # Code to be executed for each request before # the view (and later middleware) are called. response = self.get_response(request) response["Access-Control-Allow-Origin"] = "*" response["Access-Control-Allow-Headers"] = "*" # Code to be executed for each request/response after # the view is called. return response
注:未同时使用django-cors-headers和自定义中间件。
可行解决方案
- 修正中间件顺序
django-cors-headers的CorsMiddleware必须放在中间件列表最靠前的位置(至少要在CommonMiddleware之前),同时移除自定义中间件避免冲突,修改后的MIDDLEWARE列表:
MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', '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', ]
- 启用正确的CORS配置
保留必要配置,根据需求取消注释:
CORS_ORIGIN_ALLOW_ALL = True CORS_ALLOW_CREDENTIALS = True CORS_ALLOW_HEADERS = ['*'] CSRF_TRUSTED_ORIGINS = [ "http://localhost:5173", "http://127.0.0.1:5173", ]
重启Django服务
修改settings后必须完全重启开发服务器,热重载无法加载新配置。临时绕过方案(仅开发环境)
如果以上方法无效,可在前端请求时添加mode: 'no-cors',但此方式无法读取响应内容,仅适用于不需要获取返回数据的场景:
fetch('http://localhost:8000/api/students', { mode: 'no-cors' })
内容的提问来源于stack exchange,提问作者vaultdweller

