React/JS向Django发送POST Fetch请求失败的问题求助
React/JS 向 Django 发送 POST Fetch 请求的问题解决
问题背景
能正常发送 GET 请求到 Django 服务器,但发送 POST 请求时返回 403 禁止错误,具体错误信息如下:
终端错误日志
[0] Forbidden (Origin checking failed - http://localhost:3000 does not match any trusted origins.): /hello/ [0] [04/Feb/2023 08:31:02] "POST /hello/ HTTP/1.1" 403 2569
浏览器控制台错误
Form.jsx:47 POST http://localhost:8000/hello/ 403 (Forbidden)
已安装 js-cookie 并导入 Cookies,相关代码及配置如下:
现有代码及配置
Fetch 请求代码
import Cookies from 'js-cookie' // ... const response = await fetch('http://localhost:8000/hello/', { method: 'POST', headers: { "X-CSRFToken": Cookies.get('csrftoken'), "Accept": "application/json", 'Content-Type': 'application/json' }, body: JSON.stringify({ some_data: 'some_value' }) }); const data = await response.text(); console.log(data);
urls.py
urlpatterns = [ path('hello/', views.hello_world, name='hello_world'), ]
views.py
def hello_world(request): if request.method == 'POST': # do something with the data posted data = request.POST # return a JSON response return HttpResponse("Success: ") return HttpResponse("Error: ")
settings.py 配置
INSTALLED_APPS = [ ... 'corsheaders', ] MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ] # Tested using a combination of: CORS_ORIGIN_ALLOW_ALL = True CORS_ORIGIN_WHITELIST = [ "http://localhost:3000", ] CORS_ALLOW_METHODS = ['POST'] CORS_ALLOW_METHODS = [ 'DELETE', 'GET', 'OPTIONS', 'PATCH', 'POST', 'PUT', ] CORS_ALLOW_METHODS = ( 'GET', 'POST', 'OPTIONS', ) CORS_ALLOW_CREDENTIALS = True
问题分析与解决方案
核心问题是 Django 的 CSRF 验证失败,且未将前端地址加入可信源列表,结合代码和配置,需做以下修正:
1. 修正 settings.py 配置
- 重复定义的
CORS_ALLOW_METHODS会被最后一次赋值覆盖,需统一配置 CORS_ORIGIN_WHITELIST已更名为CORS_ALLOWED_ORIGINS(新版本 django-cors-headers)- 必须添加
CSRF_TRUSTED_ORIGINS,解决 Origin 不匹配问题
修正后的配置:
INSTALLED_APPS = [ ... 'corsheaders', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ... # 其他中间件保持顺序不变 ] # CORS 配置 CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", ] CORS_ALLOW_CREDENTIALS = True CORS_ALLOW_METHODS = [ 'DELETE', 'GET', 'OPTIONS', 'PATCH', 'POST', 'PUT', ] # CSRF 可信源配置 CSRF_TRUSTED_ORIGINS = [ "http://localhost:3000", ]
2. 修正视图函数获取数据的方式
发送的是 JSON 格式请求体,request.POST 无法获取数据,需解析 request.body:
import json from django.http import HttpResponse def hello_world(request): if request.method == 'POST': # 解析 JSON 请求体 data = json.loads(request.body) print(data.get('some_data')) # 输出 'some_value' return HttpResponse("Success: 数据已接收") return HttpResponse("Error: 仅接受 POST 请求")
3. 完善 Fetch 请求配置
添加 credentials: 'include',确保跨域请求携带 cookie(需配合 CORS_ALLOW_CREDENTIALS = True):
import Cookies from 'js-cookie' // ... const response = await fetch('http://localhost:8000/hello/', { method: 'POST', credentials: 'include', // 携带 cookie,保证 CSRF Token 正常传递 headers: { "X-CSRFToken": Cookies.get('csrftoken'), "Accept": "application/json", 'Content-Type': 'application/json' }, body: JSON.stringify({ some_data: 'some_value' }) }); const data = await response.text(); console.log(data);
4. 验证预检请求
跨域 POST 请求会触发 OPTIONS 预检请求,修正后的 CORS 配置已包含 OPTIONS 方法,确保中间件顺序正确即可自动处理。
完成以上修改后,重启 Django 服务器和前端项目,即可正常发送 POST 请求。
内容的提问来源于stack exchange,提问作者JAmes
相关产品推荐
相关产品推荐

