javascript - 防止浏览器卡在 AJAX 请求上

标签 javascript php jquery ajax

我目前正在尝试在用户关闭页面时发送请求。我正在使用 onbeforeunload 事件。

标签关闭页面刷新时触发事件。我的事件如下所示:

window.onbeforeunload = function () {
    $.ajax({ //jQuery
        type: "POST",
        url: "offline.php",
        data: {
            logout: 'false'
        }
    });
}; 

offline.php(这不是完整的脚本):

...
unset($_SESSION["onpage"];
if ($_POST['logout'] == "false") {
    sleep(3);
    if (isset($_SESSION["onpage"]) || !empty($_SESSION["onpage"])) die();
}
...

当用户关闭页面时,脚本会取消设置在聊天页面上设置的 session 。三秒后,脚本应检查用户是否返回但检查 onpage session 。但是,当我点击刷新按钮时,问题就来了。刷新时,页面未加载,因为三秒已完成。这导致我的整个系统被破坏。

我尝试添加 ignore_user_abort(true); 但它没有解决我的问题。还有其他方法可以使它起作用吗?

旁注:这是为了聊天。当用户关闭页面时,它应该通过“用户已离开”消息通知聊天中的其他用户。这不应在刷新时显示。当用户返回页面时,它应该通过“用户已输入”消息通知其他用户该用户已返回。

Chat

最佳答案

问题

恐怕您尝试做的事情实际上是不可能的,因为很多时候 onbeforeunload 不会被调用,由于浏览器实现、用户偏好、您的宠物斑马把你的电脑从 table 上撞下来,等等。

来自 Mozilla 的 beforeunload 文档:

Note also that various mobile browsers ignore the result of the event (that is, they do not ask the user for confirmation). Firefox has a hidden preference in about:config to do the same. In essence this means the user always confirms that the document may be unloaded.

https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload

解决方案

但这并不意味着处理用户下线是不可能的,但是。

大多数聊天 Web 应用程序改为使用心跳(一种常规的类似 ping 的请求),并使用上次 ping 之间的距离来确定用户断开连接。作为附加说明,我建议允许一个比三秒更宽的窗口来确定用户断开连接,因为 ping 可能无法在三秒时间范围内完成的原因有很多。

实现策略

您有几个选项可以实现 ping。最常见的是,人们会使用 window.setTimeout 来调用 ping,这将在完成或失败时重新启动 window.setTimeout,通常会在连续失败时加倍延迟,这样您就不会发出潜在的 -重载服务。

设置 Ping 超时:

var i = 1000;

(function ping() {
  $.ajax({
    type: "POST",
    url: "ping.php"
  }).done(function() {
    i = 1000;
    window.setTimeout(ping, i);
  }).fail(function() {
    i = i * 2;

    if (i > 60000) {
      // We don't wait to wait longer than a minute
      i = 60000;
    }

    window.setTimeout(ping, i);
  });
}());

window.setInterval 怎么样?我的代码不会更短吗?

请不要那样做。我上面关于“阻止重载服务”的注释?如果你这样做,情况会更糟。

关于javascript - 防止浏览器卡在 AJAX 请求上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36298556/

相关文章:

javascript - 本地服务的 javascript 未运行

javascript - 将外部 json 文件导入到 javascript 脚本客户端,无需外部库

javascript - Angular ng-option 按键排序

php - Laravel 以干净的方式排除资源丰富的功能

php - 根据条件运行两个不同的 SELECT 查询之一

javascript - 在全日历中禁用外部事件的突出显示

javascript - JQuery.each() : performance of anonymous function?

带有服务器时间 PHP 的 Javascript 时钟

jQuery - 取消绑定(bind)或重新绑定(bind)hoverIntent()?

javascript - 使用复选框编码和更新位 - Succinctest 方法