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

Django框架下onbeforeunload事件触发表单提交失败如何解决?

问题根因
  • 浏览器为了避免阻塞用户的页面卸载/跳转流程,默认会拦截onbeforeunload事件中所有会触发页面跳转的操作(包括同步表单提交、触发submit按钮点击),只有同步的DOM修改这类极快完成的操作才会被执行,这就是你p标签内容修改成功但表单没提交的核心原因。
  • 你写的两个提交逻辑本身冲突:调用submit()后即使没被拦截,表单已经触发提交流程,后续的$('#save').click()也不会生效。
可行解决方案

推荐使用浏览器专门为页面卸载场景设计的navigator.sendBeacon()API实现,该API的请求由浏览器后台保证发送,不会被拦截,也不会阻塞页面卸载。

具体实现步骤

  1. 先从Django页面的cookie中拿到CSRF Token,Django默认的CSRF Token存储在名为csrftoken的cookie中
  2. 在onbeforeunload事件中收集表单数据,通过sendBeacon发送给后端接口
  3. 后端适配接收数据逻辑即可

代码示例

前端修改

window.onbeforeunload = function(e){
  // 原有DOM修改逻辑保留
  document.getElementById("demo1").innerHTML="No";
  // 收集表单数据
  const form = document.getElementById('all_questions');
  const formData = new FormData(form);
  // 从cookie获取CSRF Token适配Django校验
  function getCookie(name) {
    let value = "; " + document.cookie;
    let parts = value.split("; " + name + "=");
    if (parts.length === 2) return parts.pop().split(";").shift();
  }
  formData.append('csrfmiddlewaretoken', getCookie('csrftoken'));
  // 发送请求,下方url替换为你原有表单对应的后端提交地址
  navigator.sendBeacon("/your-form-submit-url/", formData);
}

后端适配说明

原有表单提交的业务逻辑可以基本复用,仅需要把提交成功后的页面跳转逻辑改为直接返回200状态码即可,sendBeacon不需要处理前端响应。

备选方案(不推荐)

如果一定要用原生表单提交的方式,可以给form标签添加target="_blank"属性,让表单提交跳转至新页面,但是会导致用户关闭/刷新页面时弹出多余的空白标签页,体验极差,不建议使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:36:03