检测用户是否离开网页的最佳方法是什么?

onunload JavaScript事件并不是每次都有效(HTTP请求所花费的时间比终止浏览器所需的时间长)。

创建一个可能会被当前的浏览器阻止。


当前回答

为了它的价值,这是我所做的,也许它可以帮助其他人,即使文章是旧的。

PHP:

session_start();

$_SESSION['ipaddress'] = $_SERVER['REMOTE_ADDR'];

if(isset($_SESSION['userID'])){
    if(!strpos($_SESSION['activeID'], '-')){
        $_SESSION['activeID'] = $_SESSION['userID'].'-'.$_SESSION['activeID'];
    }
}elseif(!isset($_SESSION['activeID'])){
    $_SESSION['activeID'] = time();
}

JS

window.setInterval(function(){
            var userid = '<?php echo $_SESSION['activeID']; ?>';
            var ipaddress = '<?php echo $_SESSION['ipaddress']; ?>';
            var action = 'data';

            $.ajax({
                url:'activeUser.php',
                method:'POST',
                data:{action:action,userid:userid,ipaddress:ipaddress},
                success:function(response){
                     //alert(response);                 
                }
            });
          }, 5000);

Ajax调用activeUser.php

if(isset($_POST['action'])){
    if(isset($_POST['userid'])){
        $stamp = time();
        $activeid = $_POST['userid'];
        $ip = $_POST['ipaddress'];

        $query = "SELECT stamp FROM activeusers WHERE activeid = '".$activeid."' LIMIT 1";
        $results = RUNSIMPLEDB($query);

        if($results->num_rows > 0){
            $query = "UPDATE activeusers SET stamp = '$stamp' WHERE activeid = '".$activeid."' AND ip = '$ip' LIMIT 1";
            RUNSIMPLEDB($query);
        }else{
            $query = "INSERT INTO activeusers (activeid,stamp,ip)
                    VALUES ('".$activeid."','$stamp','$ip')";
            RUNSIMPLEDB($query);
        }
    }
}

数据库:

CREATE TABLE `activeusers` (
  `id` int(11) NOT NULL,
  `activeid` varchar(20) NOT NULL,
  `stamp` int(11) NOT NULL,
  `ip` text
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

基本上每隔5秒js就会发布一个php文件来跟踪用户和用户的ip地址。活动用户只是一个数据库记录,它在5秒内更新了数据库时间戳。老用户停止向数据库更新。ip地址只是用来确保一个用户是唯一的,所以网站上的2个人不会同时注册为一个用户。

可能不是最有效的解决方案,但它确实有效。

其他回答

我知道这个问题已经被回答了,但如果你只想在实际浏览器关闭时触发一些东西,而不仅仅是在页面加载发生时,你可以使用以下代码:

window.onbeforeunload = function (e) {
        if ((window.event.clientY < 0)) {
            //window.localStorage.clear();
            //alert("Y coords: " + window.event.clientY)
        }
};

在我的例子中,我正在清除本地存储并用鼠标y坐标提醒用户,只有当浏览器关闭时,这将在程序内的所有页面加载中被忽略。

在需要执行一些异步代码的情况下(比如向服务器发送消息,说明用户现在没有关注您的页面),beforeunload事件将不会给异步代码运行时间。在异步的情况下,我发现能见度变化和mouseleave事件是最好的选择。当用户更改选项卡、隐藏浏览器或将courser移出窗口作用域时,这些事件将触发。

文档。addEventListener (mouseleave, e = > { //执行一些异步代码 }) 文档。addEventListener (visibilitychange, e = > { 如果文档。visbilitystate === 'visible') { //报告用户处于焦点中 }其他{ //报告用户不聚焦 } })

Mozilla Developer Network对onbeforeunload有一个很好的描述和示例。

如果你想在离开页面之前警告用户你的页面是脏的(即如果用户输入了一些数据):

window.addEventListener('beforeunload', function(e) {
  var myPageIsDirty = ...; //you implement this logic...
  if(myPageIsDirty) {
    //following two lines will cause the browser to ask the user if they
    //want to leave. The text of this dialog is controlled by the browser.
    e.preventDefault(); //per the standard
    e.returnValue = ''; //required for Chrome
  }
  //else: user is allowed to leave without a warning dialog
});

为了它的价值,这是我所做的,也许它可以帮助其他人,即使文章是旧的。

PHP:

session_start();

$_SESSION['ipaddress'] = $_SERVER['REMOTE_ADDR'];

if(isset($_SESSION['userID'])){
    if(!strpos($_SESSION['activeID'], '-')){
        $_SESSION['activeID'] = $_SESSION['userID'].'-'.$_SESSION['activeID'];
    }
}elseif(!isset($_SESSION['activeID'])){
    $_SESSION['activeID'] = time();
}

JS

window.setInterval(function(){
            var userid = '<?php echo $_SESSION['activeID']; ?>';
            var ipaddress = '<?php echo $_SESSION['ipaddress']; ?>';
            var action = 'data';

            $.ajax({
                url:'activeUser.php',
                method:'POST',
                data:{action:action,userid:userid,ipaddress:ipaddress},
                success:function(response){
                     //alert(response);                 
                }
            });
          }, 5000);

Ajax调用activeUser.php

if(isset($_POST['action'])){
    if(isset($_POST['userid'])){
        $stamp = time();
        $activeid = $_POST['userid'];
        $ip = $_POST['ipaddress'];

        $query = "SELECT stamp FROM activeusers WHERE activeid = '".$activeid."' LIMIT 1";
        $results = RUNSIMPLEDB($query);

        if($results->num_rows > 0){
            $query = "UPDATE activeusers SET stamp = '$stamp' WHERE activeid = '".$activeid."' AND ip = '$ip' LIMIT 1";
            RUNSIMPLEDB($query);
        }else{
            $query = "INSERT INTO activeusers (activeid,stamp,ip)
                    VALUES ('".$activeid."','$stamp','$ip')";
            RUNSIMPLEDB($query);
        }
    }
}

数据库:

CREATE TABLE `activeusers` (
  `id` int(11) NOT NULL,
  `activeid` varchar(20) NOT NULL,
  `stamp` int(11) NOT NULL,
  `ip` text
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

基本上每隔5秒js就会发布一个php文件来跟踪用户和用户的ip地址。活动用户只是一个数据库记录,它在5秒内更新了数据库时间戳。老用户停止向数据库更新。ip地址只是用来确保一个用户是唯一的,所以网站上的2个人不会同时注册为一个用户。

可能不是最有效的解决方案,但它确实有效。

你能做的就是在页面加载时打开一个WebSocket连接,可以选择通过WebSocket发送数据来标识当前用户,然后在服务器上检查连接何时关闭。