【问题标题】:Sending a request back to server in onbeforeunload event在 onbeforeunload 事件中将请求发送回服务器
【发布时间】:2025-12-25 22:00:16
【问题描述】:

当用户在我的应用程序中编辑记录时,我会跟踪他们已将其“锁定”以防止其他用户在第一个用户关闭窗口(或保存)之前对其进行编辑。

我正在尝试将请求发送回服务器以解锁记录,但它在 Firefox 中不起作用。在脚本中调用 onbeforeunload 事件,但它不会将请求发送回服务器。 有什么想法吗?

<body>
<script>
    window.onbeforeunload = function (e) {
        doUnlock();
    }

function doUnlock() {
    if (navigator.appName == 'Microsoft Internet Explorer') {
        // works in IE (with an IFRAME)
        utilFrame.location.href = "/unlock.do?recordId=" + recordId;
    } else if (navigator.appName == 'Netscape') {
        // None of this works....
        //window.location.href = "/unlock.do?recordId=" + recordId;
        var req = newXMLHttpRequest();
        req.open("GET", "/unlock.do?recordId=" + recordId, true);
        req.send();
    } else {
        // Works for chrome
        window.open("/unlock.do?recordId=" + recordId);
    }
}

</script>

【问题讨论】:

  • 不确定这是否是拼写错误,但您忘记了 new 和 XMLHttpRequest() 之间的空格。
  • 是的,我应该在其中包含空间。

标签: javascript internet-explorer firefox google-chrome onbeforeunload


【解决方案1】:

newXMLHttpRequest 之间添加一个空格。

在页面卸载时,任何待处理的 (AJAX) 请求都会*取消。如果您必须在卸载时向服务器发送 AJAX 请求,请使用同步请求(不推荐!!!):

    var req = new XMLHttpRequest();
    req.open("GET", "/unlock.do?recordId=" + recordId, false); // false
    req.send();

我不推荐同步请求,因为用户界面会阻塞直到请求完成。这不是很人性化。

【讨论】:

  • 谢谢!这让我发疯了。同步不是问题,因为我不需要返回任何东西。只要它被调用,一切都很好。
  • @DanHoward 考虑为 chrome 实现 XMLHttpRequest 方法。弹出窗口非常烦人,并且可能被弹出窗口阻止程序阻止。
  • 我正在开发一个 web 应用程序,其中在卸载时发送请求(异步),它工作得很好。
  • @Pumbaa80,好的。我不知道这适用于所有浏览器。
【解决方案2】:

您应该考虑使用基于时间的锁。当用户开始编辑记录时,会使用时间戳锁定它。每 30 秒发送一个来自用户的 ping,表明该记录仍应被锁定。如果 60 秒内没有 ping,则解锁记录。

【讨论】:

  • 谢谢。这是一种有趣的方法,但需要 2 个计时器。在服务器上,计时器会引入线程问题。
  • 其实我表达的不是很好,但是你只需要在客户端上设置一个计时器。在后台你可以在返回记录之前做if lock_timestamp + 60 &gt; current_timestamp: locked = true