防止浏览器卡在AJAX请求上

Sha*_*313 3 javascript php ajax jquery

我正在尝试在用户关闭页面时发送请求.我正在使用这个onbeforeunload活动.

选项卡关闭页面刷新时会触发事件.我的活动如下:

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

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

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

当用户关闭页面时,脚本会取消设置在聊天页面上的会话.三秒钟后,脚本应检查用户是否已返回但是检查onpage会话.但是,当我按下刷新按钮时会出现问题.刷新时,页面无法加载,因为三秒钟已完成.这导致我的整个系统被破坏.

我试过添加,ignore_user_abort(true);但它没有解决我的问题.有没有其他办法让这个工作?

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

聊

doc*_*ess 7

问题

我担心你试图做的事情实际上是不可能的,因为有很多次onbeforeunload因为浏览器实现,用户偏好,你的宠物斑马将电脑从桌面上敲下来而无法调用.

来自Mozilla的beforeunload文档:

另请注意,各种移动浏览器会忽略事件的结果(即,他们不会要求用户进行确认).Firefox在about:config中有一个隐藏的首选项来做同样的事情.实质上,这意味着用户始终确认可以卸载文档.

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

解决方案

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

大多数聊天Web应用程序使用心跳(常规的类似ping的请求),并使用最后一次ping之间的距离来确定用户断开连接.另外需要注意的是,我建议允许一个比三秒钟更宽的窗口来确定用户断开连接,因为有很多原因导致ping可能无法在三秒钟内完成.

实施战略

您有几个选项来实现ping.最常见的是,人们将使用a window.setTimeout来调用ping,这将在完成或失败时重新启动window.setTimeout,通常会使连续失败的延迟加倍,因此您不会阻止可能过载的服务.

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);
  });
}());
Run Code Online (Sandbox Code Playgroud)

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

请不要这样做.我上面关于"禁止超载服务"的说明?如果你那样做会更糟糕.