如何从浏览器向服务器发送“页面将关闭”的消息?

3

我想为每个HTML文档添加一个脚本(JavaScript),向服务器发送两个消息:

  • 页面已打开
  • 页面将关闭(此消息包含页面打开的时间长度)

当文档正在加载(或加载完成)时,应发送打开消息。这是简单的部分。

当文档从浏览器视口中卸载时,应发送关闭消息。 (用户单击没有target="_blank"的链接;用户关闭浏览器选项卡/窗口;用户重新加载页面;用户退出浏览器;使页面消失的任何其他操作)

我尝试了以下方法:

//================================================================================
//Global Variables
//================================================================================
gl = {}; //container for global variables (1 scalar and 1 function)
gl.start = Math.floor(Date.now()); //timestamp of page-loading


//================================================================================
//function: Send message to server
//================================================================================
gl.sendData = function (action) {
    var message = {
        'href'     : window.location.href,
        'height'   : $(window).height(),
        'width'    : $(window).width(),
        'action'   : action,       //can be 'open' or 'close' (i.e. 'load' and 'unload')
        'rand'     : Math.random() //random number to outwit cache
    };
    if (action == 'close') {
        //how long was the page open? [milliseconds]
        message.duration = Math.floor(Date.now()) - gl.start;
    };
    window.alert(action); //debugging: show if gl.sendData is executed
    $.ajax({
        'url'     : 'http://' + window.location.hostname + '/path/to/script.pl',
        'data'    : message,
        'success' : function(){}, //not interested in server's answer
        'error'   : function(){}  //errors will be ignored
    });
};


//================================================================================
//Things to do as soon as page load is complete
//================================================================================
$(document).ready(function(){

    //send message "page did open"
    gl.sendData('open'); 

    //add event-handler to send the message "page will close" when the page is closing
    $(window).on("unload", function() {
        gl.sendData('close'); 
    });
});

页面打开时发送消息完全正常。但浏览器不发送关闭消息。

我发现了这些事实:

  • "unload" 似乎是正确的事件。当页面关闭时,警报消息弹出。
  • "beforeunload" 不起作用,因为它没有被触发(Safari on Mac,在单击导航到另一页的链接时)
  • ajax 请求在页面加载时发送,所以看起来没问题。
  • 当页面关闭时,ajax 请求不会向服务器发送数据。

我的问题:

有没有办法在文档从浏览器卸载的那一刻向服务器发送消息?
我想将页面显示的持续时间发送到服务器。还有其他方法吗?


根据您需要的准确程度,您可以使用定期的AJAX请求来“轮询”服务器,服务器只保存最后一个请求(每次覆盖之前的请求)。 - freefaller
我在考虑轮询,但我认为这会产生太多无用的消息。(准确性越高,垃圾流量就越多) - Hubert Schölnast
因此,从“depending”一词开始,正是出于这个原因。Jfriend给出了一个很好的答案。 - freefaller
1个回答

5

没有一种100%可靠的方法可以在所有浏览器中在页面关闭时将数据发送到服务器。

随着WebSockets在浏览器中的出现和普及,有些人使用从客户端到服务器的WebSockets连接来跟踪此类情况。当打开页面时,它会建立一个WebSockets(或socket.io)连接到服务器。这个连接保持了整个页面的时间。当用户离开页面或关闭浏览器时,WebSockets将被浏览器关闭。服务器可以看到WebSockets已经关闭,并将其标记为页面关闭的时间。

另一种不如WebSockets连接高效的可能性是打开的网页定期通过Ajax向服务器轮询(例如每30秒左右),以宣布页面仍然处于打开状态。当服务器看到轮询停止时,它就会假设页面已经关闭了。

这两种技术都需要与服务器进行定期连接以进行此跟踪(例如无法用于跟踪离线使用)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接