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

基于Django+React+Axios的POST请求:如何获取csrftoken Cookie?

解决Django DRF + React跨域下获取CSRF Token并POST表单的问题

你遇到的Cookie获取不到的核心原因是跨域请求下浏览器的同源策略限制,再加上代码里的几处逻辑问题,我们一步步来解决:

一、先修正Django后端的配置和视图

1. 配置跨域支持(关键!)

React运行在127.0.0.1:3000,Django在127.0.0.1:8000,属于不同端口的跨域场景。默认浏览器不会保存跨域请求的Cookie,所以需要通过django-cors-headers库开启跨域携带Cookie的支持:

  • 先安装依赖:
pip install django-cors-headers
  • 修改settings.py配置:
# 添加到INSTALLED_APPS
INSTALLED_APPS = [
    # ... 已有的其他应用
    'corsheaders',
]

# 添加中间件(注意顺序,必须放在CommonMiddleware之前)
MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    # ... 其他中间件
]

# 允许跨域请求携带Cookie
CORS_ALLOW_CREDENTIALS = True

# 指定允许的前端域名(生产环境禁止用通配符)
CORS_ALLOWED_ORIGINS = [
    "http://127.0.0.1:3000",
]

2. 修正视图函数

你的contact视图中GET请求直接返回request是错误的,Django视图必须返回HttpResponse或其子类。同时ensure_csrf_cookie装饰器需要配合合法的GET响应才能触发Cookie设置:

from django.views.decorators.csrf import ensure_csrf_cookie
from django.http import HttpResponse

@ensure_csrf_cookie
def contact(request):
    if request.method == "POST":
        # 普通Django视图用request.POST获取表单数据,DRF视图才用request.data
        print(request.POST)
        return HttpResponse("表单提交成功")
    elif request.method == "GET":
        return HttpResponse("CSRF Cookie已设置")

二、修正React前端的Axios代码

1. 全局配置跨域携带Cookie

所有Axios请求都需要开启withCredentials: true,这样浏览器才会保存跨域请求的Cookie,并在后续请求中携带它:

import axios from 'axios';
// 全局配置,避免每个请求重复写
axios.defaults.withCredentials = true;

2. 修复Cookie提取逻辑

你的getCookieValue函数判断逻辑完全写反了,导致无法正确提取csrftoken值,修正如下:

getCookieValue: function(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            // 检查Cookie是否以目标名称开头
            if (cookie.startsWith(name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    console.log("提取到的Cookie值:", cookieValue);
    return cookieValue;
},

3. 解决异步请求顺序问题

getCSRFCookie是异步操作,必须等它完成后再执行POST请求,所以要将其改为返回Promise,并在submitForm中等待它完成:

// 获取CSRF Cookie的函数,返回Promise
getCSRFCookie: async function() {
    console.log("正在获取CSRF Cookie");
    try {
        await axios.get('http://127.0.0.1:8000/customer/contact/');
        console.log("CSRF Cookie已接收");
    } catch (err) {
        console.error("获取CSRF Cookie失败:", err);
    }
},

// 提交表单的函数,确保先拿到Cookie再发送请求
submitForm: async function(bodyFormData) {
    console.log("开始提交表单");
    // 先获取CSRF Cookie(如果还未获取)
    await this.getCSRFCookie();
    
    try {
        const response = await axios({
            method: 'post',
            url: 'http://127.0.0.1:8000/customer/contact/',
            data: bodyFormData,
            headers: {
                'Content-Type': 'multipart/form-data',
                "X-CSRFToken": this.getCookieValue('csrftoken')
            }
        });
        console.log('请求成功:', response.data);
        return response.data;
    } catch (err) {
        console.error('请求失败:', err.response?.data || err.message);
        throw err; // 抛出错误方便调用方处理
    }
}

三、验证步骤

  1. 重启Django服务器,确保跨域配置生效。
  2. 在React组件加载时提前获取Cookie,比如在useEffect中:
import api from './你的API文件路径';

useEffect(() => {
  api.getCSRFCookie();
}, []);
  1. 打开Chrome开发者工具,切换到Application -> Cookies -> http://127.0.0.1:3000,此时应该能看到csrftoken Cookie。
  2. 提交表单时,检查Network面板的POST请求,确认X-CSRFToken请求头已正确设置,且Cookie已携带。

额外注意事项

  • 如果使用DRF的APIView,建议直接继承并遵循DRF的CSRF处理逻辑,但当前场景用普通视图加ensure_csrf_cookie完全可行。
  • 生产环境禁止设置CORS_ALLOW_ALL_ORIGINS = True,必须指定具体的前端域名,避免安全风险。
  • 若表单没有文件上传,Content-Type可以用默认的application/x-www-form-urlencoded,Axios会自动处理格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:07:35