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

React表单POST请求Django后端遇CSRF cookie未设置禁止错误排查

问题原因及解决方案

1. 异步函数调用错误

getCSRFToken是异步函数,直接赋值let csrftoken = getCSRFToken()得到的是Promise对象,而非实际的token值,导致请求头里的X-CSRFToken无效。

修复代码:
在createListing中用await获取真实token,同时给fetch请求添加credentials: 'include'确保跨域场景下携带cookie:

async function getCSRFToken() {
    const response = await fetch("http://127.0.0.1:8000/getCSRFToken", {
        credentials: 'include' // 确保保存Django设置的CSRF cookie
    });
    const jsonResponse = await response.json();
    console.log("CSRFToken: ", jsonResponse["token"]);
    return jsonResponse["token"];
}

async function createListing(listing) {
    let csrftoken = await getCSRFToken(); // 用await获取实际token值
    const response = await fetch(
      "http://127.0.0.1:8000/createListing/",
      {
        method: "POST",
        body: JSON.stringify(listing),
        headers: {
          "Content-Type": "application/json",
          "X-CSRFToken": csrftoken
        },
        credentials: 'include' // 跨域请求携带凭证,必填
      }
    );
    const data = await response.json();
    return data;
}

2. Django跨域配置缺失

跨域场景下,需配置Django允许前端域名的请求,并允许携带凭证:

安装并配置CORS插件

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

MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware', # 必须放在CommonMiddleware之前
    'django.middleware.common.CommonMiddleware',
    # ... 其他中间件
]

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

# 允许跨域请求携带凭证(关键,否则cookie无法传递)
CORS_ALLOW_CREDENTIALS = True

# 配置CSRF信任的前端域名
CSRF_TRUSTED_ORIGINS = [
    "http://localhost:3001",
]

3. 验证CSRF Cookie有效性

Django的CSRF验证需要同时满足两个条件:

  • 请求头X-CSRFToken的值与CSRF cookie一致
  • 请求携带了CSRF cookie

可以通过浏览器开发者工具的Application -> Cookies查看127.0.0.1:8000下是否存在csrftoken cookie,若不存在,检查getCSRFToken请求是否添加了credentials: 'include',以及Django的CORS配置是否正确。

4. 可选:简化CSRF Token获取方式

无需单独写getCSRFToken接口,直接从cookie中读取token,减少额外请求:

function getCookie(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();
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

async function createListing(listing) {
    let csrftoken = getCookie('csrftoken');
    const response = await fetch(
      "http://127.0.0.1:8000/createListing/",
      {
        method: "POST",
        body: JSON.stringify(listing),
        headers: {
          "Content-Type": "application/json",
          "X-CSRFToken": csrftoken
        },
        credentials: 'include'
      }
    );
    const data = await response.json();
    return data;
}

这种方式需要前端在初始化时(比如页面加载)发送一个带credentials: 'include'的GET请求到Django,触发CSRF cookie的设置。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 16:05:06