【问题标题】:Don't have time to send get request on window unload没有时间在窗口卸载时发送获取请求
【发布时间】:2012-03-03 09:11:21
【问题描述】:

我想在用户关闭浏览器窗口时通知服务器。

我都试过了

$(window).bind("beforeunload", function() {
    $.get("${contextPath}/notify?direction=logout");
});

$(window).unload( function() {
    $.get("${contextPath}/notify?direction=logout");
});

$(window).unload(function() {
    $.ajax({
      url: "${contextPath}/notify?direction=logout"
    });
});

但两者都不能很好地工作,尽管手册中说它可能应该这样做。

在 Firefox 中,我只在窗口关闭时没有通知,但在页面刷新时有通知。在 Chrome 中我没有。

我尝试在 Firebug 或 Chrome 开发者工具中跟踪这个脚本,发现如果跟踪它就可以开始工作了!所以我认为它不能正常工作,因为它没有时间在窗口关闭或导航之前发送请求。

这是真的吗?如何完成我的任务?

解决方案

这行得通:

$(window).bind("beforeunload",
    function() {
        $.ajax({
            async: false,
            url: 'notify'
        });
    }
);

【问题讨论】:

  • 第一个想法:AJAX 不适合这项工作。您应该使用 SJAX(同步),根据定义,AJAX 会释放 GUI 线程以继续处理 [在本例中为卸载]。
  • 查看这个答案:stackoverflow.com/a/9234785/252780

标签: javascript jquery notifications onbeforeunload onunload


【解决方案1】:

其他答案已过时,并导致其他问题,例如不可靠的信号或延迟下一页的加载。

最好的解决方案是使用navigator.sendBeacon:https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon

window.addEventListener("unload", logData, false);

function logData() {
  navigator.sendBeacon("/log", analyticsData);
}

此方法用于发送分析和诊断代码 数据到服务器。

发送分析的一个问题是网站经常想要发送 用户完成页面时的分析:例如,当 用户导航到另一个页面。在这种情况下,浏览器可能 即将卸载页面,在这种情况下浏览器可能会选择 不要发送异步 XMLHttpRequest 请求。

过去,网页尝试将页面卸载延迟足够长的时间以 发送数据。为此,他们使用了以下解决方法:

  • 使用阻塞同步 XMLHttpRequest 调用提交数据。
  • 创建一个元素并设置它的 src。大多数用户代理会 延迟卸载以加载图像。
  • 创建几秒钟的无操作循环。

所有这些方法都会阻止卸载文档,这会减慢 向下导航到下一页。下一页无能为力 为了避免这种情况,所以新页面看起来很慢,即使这是错误的 上一页。

使用sendBeacon()方法,异步传输数据 当用户代理有机会这样做时,不会延迟 卸载或下一个导航。这意味着:

  • 数据发送可靠
  • 异步发送
  • 不影响下一页的加载

【讨论】:

  • 这正是我多年来一直在寻找的解决方案。 +1,如果可以的话,我会再次投票!
  • 找了几天终于找到了解决办法。这非常有帮助@mofojed。非常感谢。
  • 我喜欢sendBeacon。唯一需要注意的是使用 POST 并且无法更改。
  • sendBeacon 现在被异步调用。所以下一个标签的性能不受影响。您可能需要编辑答案
  • @phpkode 它已经是异步的,块引用 sn-p 来自 MDN 页面,解释了其他错误/同步的方法。他们已经更新了 MDN 页面上的语言,所以我更新了这个答案以包含它。
【解决方案2】:

这非常棘手,因为浏览器不会等到响应到来,因此 ajax 请求可能会中止。

你可以在 beforeunload 事件中尝试这样的事情。

$(window).bind("beforeunload", function() {
    $.ajax({
        async: false,//This will make sure the browser waits until request completes
        url: "${contextPath}/notify?direction=logout"
    });
});

【讨论】:

  • 这是不可靠的,虽然你可以“尝试”它并且它可能会起作用,但它永远不应该在生产环境中使用。
【解决方案3】:

即使这是可能的,我仍然不会推荐它。 如果你设法让它工作,它不会在所有浏览器中工作,我仍然建议完全不要这样做。

如果您非常想知道用户何时离开您的域,请使用轮询或带有后备功能的 websocket。

您还可以在网站上给 cookie 设置一个短暂的超时时间,并使用间隔定期更新它们,这样的技巧甚至可以奏效。

此外,它在被跟踪时“开始”工作,因为该事件在下一页甚至开始加载之前就被触发了。已经有一段时间了,但上次我玩过这些事件,但是有些浏览器可能会在加载下一页时执行一段时间的代码。

【讨论】:

  • 对于我的任务来说,不是 100% 的可靠性是可以的,因为我有你说的备份解决方案。定期轮询的问题在于它不能快速工作。所以我需要一个适用于某些浏览器的快速解决方案。
【解决方案4】:

你运气不好,如果页面卸载时执行的 JavaScript 被阻塞,用户就不可能退出页面。

想象一下所有的垃圾邮件。

在某些浏览器上,会触发 unload 事件,但在您的脚本和页面清理之间会发生争用情况。

谢谢

【讨论】:

    【解决方案5】:

    我不想说这是评论,因为我正在研究这个 很久以前的情景。我会将所有信息保存到服务器 当最终用户意外或故意关闭浏览器时。一世 会告诉你..它工作得很好。,

    我说工作很好,对吧?好吧,它只适用于 Firefox 和 IE。它 在许多其他浏览器(如 Opera、Safari)中失败。

    所以我的建议是不要依赖这些函数,因为它们是 仅特定于浏览器。

    【讨论】:

      猜你喜欢
      • 2011-12-06
      • 2014-10-06
      • 2021-11-04
      • 2012-07-04
      • 2011-01-10
      • 2020-02-08
      • 2011-05-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多