三分钟,教你3种前端埋点方式!

news2025/9/2 13:27:51

目录

前言

埋点方式

基于ajax的埋点上报

介绍

代码实现

缺点

基于img的埋点上报

script及link的缺陷

基于img做埋点上报

基于Navigator.sendBeacon的埋点上报

介绍

作用

补充

例子

优势

总结

常见埋点行为

点击触发埋点

页面停留时间上报埋点

错误监听埋点

vue错误捕获

JS异常与静态资源加载异常

请求错误捕获

内容可见埋点


前言

    只有了解用户,我们才能服务好用户,而最接近用户的我们,自然要承担起更多的责任。那么在一个企业中,我们要如何去了解用户呢?最直接有效的方式就是了解用户的行为,了解用户在网站中做了什么,呆了多久。而如何去实现这一操作,这就涉及到我们前端的埋点了。

埋点方式

在聊如何进行埋点前,我们先介绍下什么是埋点?

    所谓'埋点'是数据采集领域(尤其是用户行为数据采集领域)的术语,指的是针对特定用户行为或事件进行捕获、处理和发送的相关技术及其实施过程。比如用户某个icon点击次数、观看某个视频的时长等等。
        从数据产品经理视角,聊聊埋点的意义 | 人人都是产品经理 (woshipm.com)[1]

        基于此我们可以知道埋点是实际上是对特定事件或者行为的数据监控和上报,常见的埋点上报方式有ajax,img,navigator.sendBeacon下面介绍下这三种埋点上报方式

基于ajax的埋点上报

介绍

        因为埋点实际上是对关键节点的数据进行上报是和服务端交互的一个过程,所以我们可以和后端约定一个接口通过ajax去进行数据上报。

代码实现

我们可以封装一个方法,代码如下:

function buryingPointAjax(data) {
  return new Promise((resolve, reject) => {
    // 创建ajax请求
    const xhr = new XMLHttpRequest();
    // 定义请求接口
    xhr.open("post", '/buryingPoint', true);
    // 发送数据
    xhr.send(data);
  });
}

使用时,直接调用即可

let info = {}
buryingPointAjax(info) // 这样就成功上报了info的对象

缺点

        一般而言,埋点域名并不是当前域名,因此请求会存在跨域风险,且如果ajax配置不正确可能会浏览器拦截。因此使用ajax这类请求并不是万全之策。

基于img的埋点上报

        上面可以看到如果使用ajax的话,会存在跨域的问题。而且数据上报前端主要是负责将数据传递到后端,并不过分强调前后端交互。因此我们可以通过一些支持跨域的标签去实现数据上报功能。

    script,link,img就是我们上报的数据的最好对象。先说结论,这里推荐使用img标签去实现。

script及link的缺陷

        因为埋点涉及到请求,因此我们需要保证script和link标签的src可以正常请求。如果需要请求script和link,我们需要将标签挂载到页面上。

验证缺陷

不妨验证下,我们在管理台中加入以下代码:

let a = document.createElement('script')
a.src = 'https://lf-headquarters-speed.yhgfb-cn-static.com/obj/rc-client-security/web/stable/1.0.0.28/bdms.js'

创建一个script标签,未挂载中页面上,并不会发起请求

image.png

书接上文,当我们将这个标签挂载中页面上时:

document.body.appendChild(a)

这时发起了请求

image.png

结论

    当我们使用script和link进行埋点上报时,需要挂载到页面上,而反复操作dom会造成页面性能受影响,而且载入js/css资源还会阻塞页面渲染,影响用户体验,因此对于需要频繁上报的埋点而言,script和link并不合适。

基于img做埋点上报

        通常使用img标签去做埋点上报,img标签加载并不需要挂载到页面上,基于js去new image(),设置其src之后就可以直接请求图片。

验证img优势

控制台去创建一个image标签,如下:

var img=new Image();
img.src="https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/img/MaskGroup.13dfc4f1.png";

可以看到即便未被挂载到页面上依旧发起了请求。

image.png

结论

因此当我们做埋点上报时,使用img是一个不错的选择。

  1. ·img兼容性好

  2. ·无需挂载到页面上,反复操作dom

  3. ·img的加载不会阻塞html的解析,但img加载后并不渲染,它需要等待Render Tree生成完后才和Render Tree一起渲染出来

注:通常埋点上报会使用gif图,合法的 GIF 只需要 43 个字节

基于Navigator.sendBeacon的埋点上报

        Navigator.sendBeacon是目前通用的埋点上报方案,Navigator.sendBeacon方法接受两个参数,第一个参数是目标服务器的 URL,第二个参数是所要发送的数据(可选),可以是任意类型(字符串、表单对象、二进制对象等等)。

介绍

    navigator.sendBeacon()  方法可用于通过 HTTP POST[2] 将少量数据 异步[3] 传输到 Web 服务器。

作用

        它主要用于将统计数据发送到 Web 服务器,同时避免了用传统技术(如:`XMLHttpRequest`[4])发送分析数据的一些问题。

补充

        sendBeacon 如果成功进入浏览器的发送队列后,会返回true;如果受到队列总数、数据大小的限制后,会返回false。返回ture后,只是表示进入了发送队列,浏览器会尽力保证发送成功,但是否成功了,不会再有任何返回值。

例子

以掘金为例:

image.png

这里发了一个post请求,将小量的数据发到服务端,用于统计数据

image.png

优势

        相较于img标签,使用navigator.sendBeacon会更规范,数据传输上可传输资源类型会更多。

        对于ajax在页面卸载时上报,ajax有可能没上报完,页面就卸载了导致请求中断,因此ajax处理这种情况时必须作为同步操作.

    sendBeacon是异步的,不会影响当前页到下一个页面的跳转速度,且不受同域限制。这个方法还是异步发出请求,但是请求与当前页面脱离关联,作为浏览器的任务,因此可以保证会把数据发出去,不拖延卸载流程。

总结

        前端埋点上报常使用ajax,img,navigator.sendBeacon。不推荐使用ajax。如果考虑兼容性的话,img是不二之选。目前最合适的方案是navigator.sendBeacon,不仅是异步的,而且不受同域限制,而且作为浏览器的任务,因此可以保证会把数据发出去,不影响页面卸载。

常见埋点行为

点击触发埋点

绑定点击事件,当点击目标元素时,触发埋点上报。

function clickButton(url, data) {
    navigator.sendBeacon(url, data)
}

页面停留时间上报埋点

路由文件中,初始化一个startTime,当页面离开时通过路由守卫计算停留时间。

let url = ''// 上报地址
let startTime = Date.now()
let currentTime = ''
router.beforeEach((to, from, next) => { 
     if (to) {
         currentTime = Date.now()
         stayTime = parseInt(currentTime - startTime)
         navigator.sendBeacon(url, {time: stayTime})
         startTime = Date.now()
     }
 })

错误监听埋点

通过监听函数去接收错误信息。

vue错误捕获

app.config.errorHandler = (err) => { 
    navigator.sendBeacon(url, {error: error.message, text: 'vue运行异常' })
}

JS异常与静态资源加载异常

window.addEventListener('error', (error) => { 
    if (error.message) { 
        navigator.sendBeacon(url, {error: error.message, text: 'js执行异常' })
    } else { 
        navigator.sendBeacon(url, {error: error.filename, text: '资源加载异常' })
    } 
}, true)

请求错误捕获

axios.interceptors.response.use(
  (response) => {
    if (response.code == 200) {
      return Promise.resolve(response);
    } else {
      return Promise.reject(response);
    }
  },
  (error) => {
    // 返回错误逻辑
    navigator.sendBeacon(url, {error: error, text: '请求错误异常' })
  }
);

内容可见埋点

通过交叉观察器去监听当前元素是否出现在页面

// 可见性发生变化后的回调 
function callback(data) { 
    navigator.sendBeacon(url, { target: data[0].target, text: '内容可见' }) 
} 
// 交叉观察器配置项 
let options = {}; 
// 生成交叉观察器 
const observer = new IntersectionObserver(callback); 
// 获取目标节点 
let target = document.getElementById("target"); 
// 监听目标元素 
observer.observe(target);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/619376.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人工电场算法(AEFA)(含MATLAB代码)

先做一个声明:文章是由我的个人公众号中的推送直接复制粘贴而来,因此对智能优化算法感兴趣的朋友,可关注我的个人公众号:启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法,经典的,或者是近几年…

8种Python异常检测算法总结

异常检测是通过数据挖掘方法发现与数据集分布不一致的异常数据,也被称为离群点、异常值检测等等。本文为大家整理了8个常见的Python异常检测算法,希望对大家有所帮助 一、异常检测简介 异常检测是通过数据挖掘方法发现与数据集分布不一致的异常数据&…

Centos7系统部署搭建Kafka集群

kafka集群搭建 一、环境准备1.1 服务器准备1.2 版本信息1.3 启动kafka环境1.3.1 获取kafka1.3.2 启动kafka1.3.2.1 kafka && ZooKeeper1.3.2.2 kafak && KRaft 1.4 创建主题1.5 事件写入主题1.6 事件读取1.7 停止kafka环境 二、搭建 kafka 集群2.1 ZooKeeper 集…

chatgpt赋能python:Python如何读取照片

Python如何读取照片 介绍 Python是一种高级编程语言,其简单易用、可扩展性强等特点,使其在数据分析、机器学习等领域得到了广泛应用。而在图像处理领域,Python同样也有着较为优异的表现。本文将介绍Python读取照片的方法,并探讨…

普通2本,去过字节外包,到现在年薪30W+的测试开发,我的2年转行心酸经历...

个人简介 我是一个普通二本大学机械专业毕业,17年毕业,19年转行,目前做IT行业的软件测试已经有3年多,职位是高级测试工程师,坐标上海… 我想现在我也有一点资格谈论关于转行这个话题;希望你在决定转行之前…

Linux下面安装jdk和tomcat

1、jdk的安装 1、上传jdk到 opt目录下面 2、解压jdk tar -xvf jdk-8u281-linux-x64.tar.gz3、一般把jdk放到/usr/local (软件的安装都是放到usr下面) mv jdk1.8.0_281 /usr/local/4、配置环境变量 找到 /etc/profile 进行编辑修改 export JAVA_HOM…

速下载 | 200页幻灯片图解新版《商用密码管理条例》

国家高度重视商用密码工作。2023年4月14日,国务院常务会议审议通过了《商用密码条例》(以下简称《条例》)修订草案。5月24日中华人民共和国中央人民政府网站正式公开修订后的正式稿全文。本次《条例》在密码法框架下进行了全面修订&#xff0…

面试“我“又踩坑了,高频软件测试面试题,项目经验板块(付答案)...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 问题1&#xff1a…

(学习日记)2023.06.07

写在前面: 由于时间的不足与学习的碎片化,写博客变得有些奢侈。 但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。 既然如此 不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录&a…

基于ChatGPT使用报告 (针对嵌入式领域测试及心得)

目录 1、基于驱动的日志解析提问 错误日志分析【100%】 报错日志分析【90%】 错误日志分析【60%】 2、基于安卓设备调试提问 adb调试i2c【效率50%】 adb调试gpio【50%】 3、基于高通代码的提问 基于高通代码含义的解析【效率80%】 基于高通新增TP驱动提问【效率50%】…

【区块链 | L2】详解Layer 2扩展解决方案Optimism(OP)是如何工作的?

Optimism是一个快速、稳定、可扩展和低成本的以太坊Layer 2区块链。这意味着它在以太坊区块链(Layer1)之上运行,以帮助缓解拥塞,进而降低交易成本和处理时间。作为现有以太坊软件的最小扩展,Optimism的EVM-equivalent 架构可以扩展以太坊应用程序。如果它能在以太坊上工作…

移动端的加解密

目录 引言 算法分类 密钥介绍 模式介绍 算法介绍 小结 写在最后 引言 今天给大家分享一篇有关移动端加解密的文章。随着移动设备的普及,加密技术在保护用户数据方面变得越来越重要。 本文将为您介绍Android加解密算法的分类、优缺点特性及应用,…

前端Vue实现国际化

国际化实现原理 假设我们有一个变量 msg,但是这个 msg 有两个值,一个是 hello,一个是 你好,现在需要我们根据需要切换 msg 的值,如何做呢? // 定义 msg 值的数据源 const msgList {en: {msg: hello},zh:…

智能批量复制文件,轻松实现文件批量复制并实现编号

您有没有遇到过需要将相同类型的多个文件复制到不同文件夹的情况?这个过程可能会非常耗时,尤其当文件的数量很大且需要进行重复编号时,更是一项非常烦琐的工作。细有一个快手的方法可以实现,如下: 首先,第…

基于spring boot框架访问zookeeper

本地部署zookeeper: 进入zookeeper-3.3.6/conf目录下,将zoo_sample.cfg文件改名为zoo.cfg,再用文本编辑器打开这个文件,修改如下红框位置的内容,改成本地一个可以访问的已有目录: 打开命令行窗口&#xff…

高考开始了,计算机专业未来还会火吗?

2023年高考,今天开始第一场考试。而走出考场,考生们也将面临选报专业的难题。高考人数逐年攀升,录取率却不断下降。 过去10年,计算机专业可谓红透半边天,早早进入这个行业的,基本都吃到了很高的红利。然而…

动态规划母题:01背包问题

1. 前置知识 动态规划与图论,前缀和与差分等有模板的算法不同,动态规划更考察思维能力,而不是运用模板的能力。 个人认为 Acwing 关于动态规划的讲解比较容易理解。我会根据 Acwing 的动态规划解题思路来讲解题目。 虽说动态规划没有固定的模…

基于Locust实现MQTT协议服务的压测脚本

一、背景简介 业务背景大概介绍一下,就是按照国标规定,车辆需要上传一些指定的数据到ZF的指定平台,同时车辆也会把数据传到企业云端服务上,于是乎就产生了一些性能需求。 目前我们只是先简单的进行了一个性能场景的测试&#xf…

PMP考试到底难在哪里?

那么,PMP考试到底难在哪? 01涉及面广 目前PMP考试内容大部分来源于教材《PMBOK指南》和《敏捷实践指南》。 作为考试出题的知识基础《PMBOK指南》,总共有700多页,所覆盖的知识面很广。 另一方面,根据最新版考纲&am…

使用大型语言模(LLM)构建系统(二):内容审核、预防Prompt注入

今天我学习了DeepLearning.AI的 Building Systems with LLM 的在线课程,我想和大家一起分享一下该门课程的一些主要内容。 下面是我们访问大型语言模(LLM)的主要代码: import openai#您的openai的api key openai.api_key YOUR-OPENAI-API-KEY def get_…