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

使用Fetch更新数据库时出现CSRF Token缺失错误

解决Fetch POST请求403 Forbidden(CSRF Token缺失)问题

我尝试用Fetch API更新数据库条目时,控制台出现403 Forbidden错误,日志提示CSRF Token缺失。我的HTML未使用表单,仅通过JS将元素追加到div中,相关代码如下:

document.addEventListener("DOMContentLoaded", function(){

    const button = document.querySelectorAll("#edit_profile")
    button.forEach(function(button){
        button.onclick = function(){
      
            const memberID = button.dataset.id;
            const usernameID = button.dataset.username;
            const username = document.getElementById(`username_${memberID}`);

            let edit_username = document.createElement("textarea");
            edit_username.setAttribute("rows", "1");
            edit_username.innerHTML = username.innerHTML
            edit_username.id = `edit_username_${memberID}`;
            edit_username.className = `form-control username ${usernameID}`;

            const saveButton = document.createElement("button");
            saveButton.innerHTML = "Save";
            saveButton.id = `saveButton_${memberID}`;
            saveButton.className = "btn btn-success col-3";
            saveButton.style.margin = "10px";

            document.getElementById(`edit_${memberID}`).append(edit_username);
            document.getElementById(`edit_${memberID}`).append(saveButton);

            saveButton.addEventListener("click", function(){
                edit_username = document.getElementById(`edit_username_${memberID}`);

                fetch(`/edit_profile/${memberID}`,{
                    method: "POST",
                    body: JSON.stringify({
                        username: edit_username.value,
                    })
                })
                .then(response => response.json())
                .then(result => {
                    console.log(result);
                    if(result[`error`]){
                    reset(memberID)
                    } 
                    else {
                        username.innerHTML = result.username;
                        reset(memberID) 
                        
                    }
                })
                .catch(error => {
                    console.error(error);
                })
               
            })

        }
    });
});

问题原因

后端启用了CSRF(跨站请求伪造)防护机制,所有POST请求必须携带有效的CSRF Token才能通过验证,你的Fetch请求没包含这个Token,所以被拦截返回403。

解决方案

方法1:从页面meta标签获取Token并添加到请求头

首先确认HTML页面中存在后端生成的CSRF Token meta标签(大多数后端框架会自动注入,比如Django、Flask-WTF):

<meta name="csrf-token" content="后端生成的CSRF Token值">

然后修改Fetch请求代码,添加请求头:

saveButton.addEventListener("click", function(){
    edit_username = document.getElementById(`edit_username_${memberID}`);
    // 获取meta标签中的CSRF Token
    const csrfToken = document.querySelector('meta[name="csrf-token"]').content;

    fetch(`/edit_profile/${memberID}`,{
        method: "POST",
        headers: {
            'Content-Type': 'application/json', // 必须指定JSON格式
            'X-CSRFToken': csrfToken // 添加CSRF Token请求头
        },
        body: JSON.stringify({
            username: edit_username.value,
        })
    })
    .then(response => response.json())
    .then(result => {
        console.log(result);
        if(result.error){
            reset(memberID)
        } 
        else {
            username.innerHTML = result.username;
            reset(memberID) 
        }
    })
    .catch(error => {
        console.error(error);
    })
})

方法2:从Cookie读取CSRF Token(部分框架支持)

如果后端将CSRF Token存储在Cookie中(比如Django默认存在csrftoken Cookie),可以通过JS读取Cookie并添加到请求头:

// 封装读取Cookie的函数
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;
}

// 修改Fetch请求部分
saveButton.addEventListener("click", function(){
    edit_username = document.getElementById(`edit_username_${memberID}`);
    const csrfToken = getCookie('csrftoken'); // 替换为对应Cookie名称

    fetch(`/edit_profile/${memberID}`,{
        method: "POST",
        headers: {
            'Content-Type': 'application/json',
            'X-CSRFToken': csrfToken
        },
        body: JSON.stringify({
            username: edit_username.value,
        })
    })
    // 后续then/catch逻辑不变
})

注意事项

  • 发送JSON数据时,必须设置Content-Type: application/json请求头,否则后端无法正确解析请求体
  • 不同后端框架的CSRF请求头名称可能不同,比如部分框架使用X-CSRF-TOKEN,请根据后端配置调整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 02:40:55