Django+React跨域报错:Request header字段不被Access-Control-Allow-Headers允许
解决Django+React POST请求的CORS错误
问题根源
你在前端请求头里加了一堆后端才应该返回的响应头字段(比如Access-Control-Allow-Origin、Access-Control-Allow-Methods这些),这些字段不属于前端请求头的合法内容,后端的CORS配置没允许这些自定义头,所以预检请求被拦截了。
修复步骤
1. 修正React请求代码
把请求头里的响应头字段全部删掉,只保留前端请求需要的必要字段,同时注意withCredentials是axios的配置项,不是请求头的一部分,要放到axios的config对象里,而非headers对象中。
修改后的代码:
var csrftoken = getCookie("csrftoken"); function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie !== "") { var cookies = document.cookie.split(";").map(cookie => cookie.trim()); for (var i = 0; i < cookies.length; i++) { var cookie = cookies[i]; if (cookie.startsWith(name + "=")) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } // 只保留必要的请求头 const requestHeaders = { "X-CSRFToken": csrftoken, "Content-Type": "application/json", }; axios .post( baseURL, { title: "title from react", description: "description from react", }, { headers: requestHeaders, withCredentials: true, // 此为axios配置项,不属于请求头 } ) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); });
2. 修正Django视图的JSON数据解析(关键补充)
你当前的Django视图是针对表单提交设计的(用request.POST),但前端发送的是JSON格式数据,request.POST只能解析application/x-www-form-urlencoded编码的表单数据,无法直接读取JSON,需要手动解析:
import json from django.http import JsonResponse from django.shortcuts import render from django.views.generic.edit import CreateView from .forms import PackageForm from django.utils.decorators import method_decorator from django.views.decorators.csrf import ensure_csrf_cookie class PackageFormView(CreateView): form_class = PackageForm initial = {'key': 'value'} template_name = 'package_form.html' def get(self, request, *args, **kwargs): form = self.form_class(initial=self.initial) return render(request, self.template_name, {'form': form}) @method_decorator(ensure_csrf_cookie) def post(self, request, *args, **kwargs): # 解析前端发送的JSON数据 data = json.loads(request.body) form = self.form_class(data) if form.is_valid(): form.save() return JsonResponse({"status": "success"}) return JsonResponse({"errors": form.errors}, status=400)
3. 简化并规范Django CORS配置
你的现有配置存在冗余(CORS_ORIGIN_ALLOW_ALL = True会覆盖CORS_ALLOWED_ORIGINS),建议保留精准配置:
# settings.py INSTALLED_APPS = [ # ... 其他已安装应用 ... 'corsheaders', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'corsheaders.middleware.CorsMiddleware', # 必须放在CommonMiddleware之前 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] CORS_ALLOWED_ORIGINS = [ 'http://localhost:3000', ] 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", "cache-control", ] CSRF_TRUSTED_ORIGINS = ['http://localhost:3000']
完成以上修改后,重启Django和React服务,即可解决CORS拦截问题。
内容的提问来源于stack exchange,提问作者Vincent Roye
相关产品推荐
相关产品推荐

