页面停留时长、日志上报,你们都是怎么玩的?

01 引言

在业务中,我们很多时候需要记录用户的行为。但是并不是所有的行为都会和服务端交互,服务端就显的心余而力不足。

尤其在一些类似支付、拍卖等过程中引起的纠纷。用户或没有什么都没有操作被扣款了,但是因为和服务端没有交互,并不到任何的线索。这时候就需要前端采集用户的行为日志,然后按需上报,以记录用户的页面行为。

有需求,就有市场。类似的框架应运而生如,美团的Logan、神策网络的神策等。为了分析用户的行为喜好,页面的停留时长就变的尤为紧要。

我们就以后端的视角,窥探一下前端技术。

02 难点

用户的行为日志记录相对比较简单,但是页面的停留时长似乎有点难。难点如下:

  • 用户打开监控页面,又打开新的页面算不算离开?
  • 用户将页面最小化,算不算离开?
  • 用户将页面最大化,停留时长要不要重新计算?
  • 用户关闭新开页后,重新回到监控页面,停留时长要不要算?

其实,关于算不算,要不要算是产品问题。从技术角度来看,我们通过什么样的方式或者函数能够监控这些变化呢?

有两种方式可供参考:

  • pagehide | pageshow
  • visibilitychange

03 pagehide | pageshow

当浏览器从展示会话历史中的另一个页面过程中隐藏当前页面时,会向 Window 发送 pagehide 事件。例如,当用户点击浏览器的后退按钮时,在显示前一个页面之前,当前页面会接收到一个 pagehide 事件。

当一条会话历史记录被执行的时候将会触发页面显示 (pageshow) 事件。(这包括了后退/前进按钮操作,同时也会在 onload 事件触发后初始化页面时触发)

3.1 pagehide

pagehide是基于window的事件,简单来说,就是页面被覆盖或者关闭时,触发该事件。

js 复制代码
window.addEventListener('pagehide', function(event) {
    console.info("页面被关闭了");
});

// 另外一种写法
window.onpagehide = (event) =>{
    console.info("页面被关闭了");
}

文档地址:

developer.mozilla.org/zh-CN/docs/...

3.2 pageshow

pageshow 同样是基于window的事件,简单来说,就是页面只要被重新加载,就会触发该事件。

js 复制代码
window.addEventListener('pageshow', function(event) {
    console.info("页面被关闭了");
});

// 另外一种写法
window.onpageshow = (event) =>{
    console.info("页面被关闭了");
}

文档地址:

developer.mozilla.org/zh-CN/docs/...

3.3 实战

页面的开启和关闭,我们都想服务端发送请求,其中发送请求的方法:

navigator.sendBeacon(url, data)

文档地址:

developer.mozilla.org/zh-CN/docs/...

案例:

js 复制代码
$(function (){
    window.addEventListener('pagehide', function(event) {
        const formData = new FormData();
        formData.append('data', '窗口关闭了!');
        navigator.sendBeacon("/file/windowClose", formData);
    });

    window.onpageshow = (event) =>{
        const formData = new FormData();
        formData.append('data', '窗口打开了!');
        navigator.sendBeacon("/file/windowOpen", formData);
    }
});
java 复制代码
@RequestMapping("windowClose")
public void windowClose(String data) {
    System.out.println("window is closed......" + data);
}

@RequestMapping("windowOpen")
public void windowOpen(String data) {
    System.out.println("window is opened......" + data);
}

结果:

3.5 浏览器兼容

04 visibilitychange

当其选项卡的内容变得可见或被隐藏时,会在 document 上触发 visibilitychange 事件。

文档地址:

developer.mozilla.org/zh-CN/docs/...

4.1 案例

JS代码:

js 复制代码
document.addEventListener("visibilitychange", function logData() {
    if (document.visibilityState === "hidden") {
        const formData = new FormData();
        formData.append('data', '窗口关闭了!');
        navigator.sendBeacon("/file/windowClose", formData);
    }
});

document.onvisibilitychange = (event) => {
    if (document.visibilityState === "visible") {
        const formData = new FormData();
        formData.append('data', '窗口打开了!');
        navigator.sendBeacon("/file/windowOpen", formData);
    }
}

也可以使用Jquery绑定事件:

js 复制代码
$(document).on('visibilitychange', function() {
    if (document.visibilityState === 'hidden') {
        // 关闭
    }else if (document.visibilityState === 'visible'){
        // 显示
    }
});

结果:

4.2 浏览器兼容性

05 小结

两种方式都存在兼容性问题,移动端适用不适用,怎么也不清楚,总之应用在PC端,案例并没有问题。这两种方式就能监控窗口的显示和关闭,用来统计用户的浏览时长,同时也可以用户类似Websocket等客户端的关闭。收藏以后备用。

相关推荐
驭渊的小故事28 分钟前
MyBatis XML 开发实战:从配置到 CRUD 全解析
xml·java·mybatis
Jmyd01235 小时前
Web端3D营销展厅技术实现路径:从素材上云到线索回流的数据链路
前端·3d·性能优化·三维数字化
哦虎!5 小时前
【JavaEE】网络初识
java
半个落月6 小时前
LangChain Agent 中间件实战(上):生命周期、状态、短路与工具包
javascript·langchain
砚凝霜6 小时前
【软考信息安全】第二十二章 Web服务器安全分析与增强——Apache与IIS
服务器·前端·安全
for_ever_love__6 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
半个落月6 小时前
LangChain Agent 中间件实战(下):DeepAgents文件权限、长期记忆与对话摘要
javascript·langchain
我是人✓6 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
欣栀♡7 小时前
JVM 频繁 Full GC 先看日志括号里的 cause,jstat 的 FGC 在 JDK 8 上会骗人
java·jvm
IT研究室7 小时前
最新计算机毕业设计选题推荐-基于spring boot的葡萄酒文化宣传网站-网站-文档指导-Java-springboot
java·spring boot·课程设计