You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Django中Axios POST请求CSRF验证失败问题求助

解决Django + React Axios POST请求的CSRF验证失败问题

我之前也遇到过一模一样的问题,折腾了好一阵子才搞定,结合你的代码和情况,给你几个关键的解决步骤:

1. 先修正Django视图的JSON解析问题

你当前的视图用了request.POST['username'],但Axios发送的是Content-Type: application/json格式的数据——Django的request.POST只能解析application/x-www-form-urlencoded或multipart/form-data类型的请求体,JSON数据需要从request.body中读取并解析。修改你的视图代码:

import json
from django.http import JsonResponse

def createUser(request):
    if request.method != 'POST':
        return JsonResponse({'error': 'Method not allowed'}, status=405)
    
    # 解析JSON请求体
    try:
        data = json.loads(request.body)
    except json.JSONDecodeError:
        return JsonResponse({'error': 'Invalid JSON'}, status=400)
    
    username = data.get('username')
    email = data.get('email')
    
    resp = {
        'username': username,
        'email': email
    }
    return JsonResponse(resp)

2. 确保Axios的CSRF配置正确生效

你已经设置了xsrfHeaderName和xsrfCookieName,但还缺了一个关键配置:跨域请求时携带Cookie。默认情况下,Axios在跨域请求时不会发送Cookie,而Django的CSRF Token是存在Cookie里的,所以必须开启withCredentials:

方式一:全局配置(推荐)

在你的React项目入口文件(比如index.js)里添加:

import axios from 'axios';

// 全局配置Axios
axios.defaults.withCredentials = true;
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";

方式二:单个请求配置

如果不想全局开启,也可以在每个POST请求里单独设置:

axios.post('http://localhost:8000/api/createUser/',{
    username : 'xyz',
    email : 'xyz@gmail.com'
}, {
    headers: {
        'Content-Type': 'application/json',
    },
    withCredentials: true // 关键配置
});

3. 配置Django的CORS(跨域资源共享)

如果你的React项目运行在localhost:3000,Django在localhost:8000,属于跨域场景,需要安装并配置django-cors-headers来允许跨域请求携带Cookie:

  1. 安装依赖:
pip install django-cors-headers
  1. 修改settings.py:
INSTALLED_APPS = [
    # ... 其他应用
    'corsheaders',
]

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware', # 放在最前面
    'django.middleware.common.CommonMiddleware',
    # ... 其他中间件,确保CsrfViewMiddleware在里面
    'django.middleware.csrf.CsrfViewMiddleware',
]

# 允许的前端域名
CORS_ALLOWED_ORIGINS = [
    "http://localhost:3000",
]

# 允许携带Cookie
CORS_ALLOW_CREDENTIALS = True

# 配置CSRF Cookie的SameSite属性(根据你的环境调整)
CSRF_COOKIE_SAMESITE = 'Lax'
SESSION_COOKIE_SAMESITE = 'Lax'

# 如果是HTTPS环境,需要开启下面两个配置
# CSRF_COOKIE_SECURE = True
# SESSION_COOKIE_SECURE = True

4. 验证CSRF Token是否正确携带

发送请求前,打开浏览器的开发者工具(F12),切换到Network标签,找到你的POST请求:

  • 检查Request Headers里是否有X-CSRFTOKEN字段,且值和Cookie里的csrftoken一致;
  • 检查Cookies里是否存在csrftoken。

如果没有csrftokenCookie,可以通过一个单独的Django视图获取Token:

from django.middleware.csrf import get_token
from django.http import JsonResponse

def get_csrf_token(request):
    return JsonResponse({'csrfToken': get_token(request)})

然后在React里先请求这个接口拿到Token,再手动设置到Axios的headers里:

axios.get('http://localhost:8000/api/get-csrf-token/')
  .then(response => {
    const csrfToken = response.data.csrfToken;
    axios.post('http://localhost:8000/api/createUser/', {
      username: 'xyz',
      email: 'xyz@gmail.com'
    }, {
      headers: {
        'X-CSRFTOKEN': csrfToken,
        'Content-Type': 'application/json'
      },
      withCredentials: true
    });
  });

按照这些步骤调整后,你的CSRF验证应该就能通过了,同时视图也能正确解析JSON数据。

内容的提问来源于stack exchange,提问作者Andro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:07:36