Django项目PUT请求后页面刷新致CSRFToken暴露的AJAX问题排查
解决Django表单PUT提交后页面刷新及CSRF Token暴露问题
嘿,我看你折腾了好几种方法还是没搞定页面刷新的问题,核心原因其实是异步表单提交的回调逻辑没处理好,浏览器没法识别你的阻止指令。我帮你梳理下问题,再给你修正后的代码:
问题根源拆解
- async函数的返回值坑:浏览器的
onsubmit事件只认布尔值来阻止默认行为,但async函数默认返回Promise,哪怕你写了return false,也会被包装成Promise,浏览器根本不买账,默认的表单提交还是会触发。 - 无效的函数调用:代码里的
edit_prod.handleForm()完全没定义,属于多余的无效代码,反而可能打乱逻辑。 - 没捕获事件对象:你没拿到表单提交的事件实例,没法直接用最可靠的
event.preventDefault()来阻断刷新。 - 表单赋值错误:给输入框用
innerHTML赋值是错的,表单元素得用value属性来设置内容。
修复后的完整代码
// 定义表单提交使用的全局变量 var id, upt_prodName, upt_prodPrice, upt_prodDescpt; // 填充文本区域以允许用户更新产品信息的代码块 const editProd_view = (response) => { let prod_id = response.id; let edit_name = response.name; let edit_price = response.price; let edit_descpt = response.description; // 修正:表单元素用value赋值,不是innerHTML document.querySelector("#prod_idUpt").innerHTML = prod_id; document.querySelector("#editProdName").value = edit_name; document.querySelector("#editProdPrice").value = edit_price; document.querySelector("#editProdDescpt").value = edit_descpt; id = prod_id; // 提交时发送产品信息以更新产品 document.querySelector("#editProd_form").onsubmit = async (event) => { // 第一步:立即阻止默认提交行为,这是最可靠的方式 event.preventDefault(); try { // 获取文本区域中的所有值以更新内容 upt_prodName = document.getElementById("editProdName").value; upt_prodPrice = document.getElementById("editProdPrice").value; // 统一变量名,避免提交数据错误 upt_prodDescpt = document.getElementById("editProdDescpt").value; // 修正:await和then不要混用,保持代码清晰 const res = await fetch(`/editProduct/${id}`, { method: "PUT", headers: { "Content-Type": "application/json", "X-CSRFToken": getCookie("csrftoken"), }, body: JSON.stringify({ name: upt_prodName, description: upt_prodDescpt, price: upt_prodPrice, }), }); const result = await res.json(); console.log("result ->", result); // 这里可以加提交成功后的逻辑,比如关闭编辑弹窗、刷新产品列表等 } catch (err) { console.error("err", err); } }; return false; }; // 确保getCookie函数正常工作(如果还没定义的话) 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; }
核心修复点说明
- 优先用
event.preventDefault():把这个放在异步逻辑最开头,不管后续代码执行情况如何,都能直接阻断页面刷新。 - 修正表单赋值方式:输入框、文本域这类表单元素必须用
value属性设置内容,innerHTML是给普通标签用的。 - 统一变量名:之前的
new_prodPrice和全局变量upt_prodPrice不一致,会导致提交的数据错误,现在统一成同一个变量。 - 简化异步代码:
await和.then()混用会让逻辑混乱,统一用await让代码更易读。
这样修改后,表单就会通过AJAX完成PUT请求,不会触发页面刷新,CSRF Token也就不会暴露在URL里了。
内容的提问来源于stack exchange,提问作者cl0r1
相关产品推荐
相关产品推荐

