$(window).unload在离开网页之前等待AJAX​​调用完成

时间:2010-06-29 06:59:07

标签: javascript jquery ajax

基本上,一旦用户在我的应用程序中留下网页,我需要使用AJAX调用PHP脚本,这将在网页上花费一些时间到数据库,然后离开页面。

等待AJAX​​请求完成非常重要,因为用户无法访问我的应用程序中的网页,除非他们在上一页上花了一定时间(比方说两分钟)。

这是我的jquery代码:

$(document).ready(function() {

    var teid = TEID;
    var startTime = new Date().getTime();

    $(window).unload(function() {
        var timeSpentMilliseconds = new Date().getTime() - startTime;
        var t = timeSpentMilliseconds / 1000 / 60;

        $.ajax({
            type: 'POST',
            url: '/clientarea/utils/record-time',
            data: 'teid=' + teid + '&t=' + t
        });
    });

});

如何更改它以便在离开网页之前等待AJAX​​请求结束?

编辑:

或者更好(更容易)让AJAX请求每分钟重复一次。这可能吗?

8 个答案:

答案 0 :(得分:31)

好吧,您可以在AJAX调用上设置async: false以使浏览器在执行任何其他操作之前等待请求完成,但请注意,这将在请求期间“挂起”浏览器。 / p>

$.ajax({
    type: 'POST',
    async: false,
    url: '/clientarea/utils/record-time',
    data: 'teid=' + teid + '&t=' + t
});

从手册:

  

默认情况下,所有请求都是异步发送的(默认情况下设置为true)。如果需要同步请求,请将此选项设置为false。跨域请求和dataType:“jsonp”请求不支持同步操作。请注意,同步请求可能会暂时锁定浏览器,并在请求处于活动状态时禁用任何操作。

答案 1 :(得分:7)

最佳解决方案是使用navigator.sendBeacon。它是全新的功能,开始在新版本的浏览器中实现。该功能适用​​于比Chrome 39和Firefox 31更新的浏览器。在撰写本文时,Internet Explorer和Safari不支持此功能。要确保您的请求在不支持新功能的浏览器中发送,您可以使用此解决方案:

var navigator.sendBeacon = navigator.sendBeacon || function (url, data) {
  var client = new XMLHttpRequest();
  client.open("POST", url, false); // third parameter indicates sync xhr
  client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
  client.send(data);
};

希望这有帮助!

答案 2 :(得分:6)

如何在卸载处理程序中设置cookie?服务器应该在后续请求中看到它。

<script>
    $(window).unload(function(){document.cookie='left_on='+(new Date())})
</script>

答案 3 :(得分:4)

对我来说,你的浏览器在关闭之前等待并不是一个好主意...
因为如果我真的要关闭它会怎么样?...

如果页面打扰了用户,那就不好了......

我的建议是,在页面中,你等待2分钟(如果需要2分钟),然后发送一个用户已完成2分钟的ajax ...

然后你可以在服务器端检查它是否有2分钟......

答案 4 :(得分:2)

尝试劫持用户的浏览器是一个坏主意,因为它会给他们带来不好的感觉并将其发送出去。

如果由于某种原因你想要在用户花费最少时间之前不要生成新页面,那么最好的办法是引导服务器端,即重定向到当前页面,直到请求的时间为止过去了。

您甚至不需要进行ajax调用,只需在会话中存储服务页面的时间戳,并且在经过一定时间后才显示以下页面。

请务必告诉用户他们必须等待新页面准备好,可能需要简单的javascript倒计时。

如果您希望用户实际将页面激活一段时间(即不要切换到另一个标签/窗口等待两分钟的时间),那么,我无法提出有效的解决方案。

答案 5 :(得分:1)

使用onbeforeunload

$(document).ready(function(){
  window.onbeforeunload = function(){
     // $.ajax stuff here
     return false;
  }
});

这至少会给用户一个messagebox,询问他是否要关闭当前窗口/标签。

答案 6 :(得分:1)

我认为按照你的建议使用轮询技术要好得多,尽管它会对网络服务器造成一些负担。

$(document).ready(function() {

    var teid = TEID;
    var startTime = new Date().getTime();

    var ajaxFunc = function() {
        var timeSpentMilliseconds = new Date().getTime() - startTime;
        var t = timeSpentMilliseconds / 1000 / 60;

        $.ajax({
            type: 'POST',
            url: '/clientarea/utils/record-time',
            data: 'teid=' + teid + '&t=' + t
        });
    };

    setInterval(ajaxFunc, 60000);

})

当你可以使用websockets时,你会很高兴:)

答案 7 :(得分:0)

jQuery.ajax()方法有async选项。如果将其设置为false,则呼叫将阻止,直到响应返回(或超时)。我非常害羞,调用它,会让浏览器在卸载处理程序中消失。

旁注:你不能依靠这个来工作。如果浏览器为用户提供取消卸载处理程序的选项(某些浏览器在等待一段时间后会执行此操作),则“站点上的时间花费”将永远不会更新。您可以向站点添加计时器,该计时器会定期调用服务器上的脚本并更新时间。您将没有准确的值,但在您的情况下,这不是必需的。

如果您只需要知道用户是否在页面上是X秒您可以在onload处理程序中设置超时(使用setTimeout(function, ms)),如果用户花费了所需的时间,则会发出呼叫。所以不需要卸载处理程序。