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

article/2025/10/8 8:42:30

作者:彩虹修狗

https://juejin.cn/post/7224132741997281338

前言

只有了解用户,我们才能服务好用户,而最接近用户的我们,自然要承担起更多的责任。

那么在一个企业中,我们要如何去了解用户呢?
最直接有效的方式就是了解用户的行为,了解用户在网站中做了什么,呆了多久。
而如何去实现这一操作,这就涉及到我们前端的埋点了。

埋点方式

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

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

我们可以知道埋点是实际上是对特定事件或者行为的数据监控和上报,常见的埋点上报方式有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标签,未挂载中页面上,并不会发起请求

84425846c21c8dbac86997bc80cdff24.jpeg

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

document.body.appendChild(a)

这时发起了请求

12bc2e7e6b3db586c8869497b9d899ee.jpeg

结论

当我们使用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";

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

c91df041e8583a49a775f8c0c968f961.jpeg

结论

因此当我们做埋点上报时,使用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[1] 将少量数据 异步[2] 传输到 Web 服务器。

作用

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

补充

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

例子

以掘金为例:

0c4dac8e342200b38ced756a9eedfa08.jpeg

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

7487da03202da1ef6c0ea3cd02c1b82d.jpeg

优势

相较于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);

参考资料

[1]

HTTP POST: https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/POST

[2]

异步: https://developer.mozilla.org/zh-CN/docs/Glossary/Asynchronous

[3]

XMLHttpRequest: https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest


http://chatgpt.dhexx.cn/article/k2l7vlUW.shtml

相关文章

前端数据埋点

数据埋点,是一种常用的数据采集方法。埋点是数据的来源,采集的数据可以帮助业务人员分析网站或者App的使用情况、用户行为习惯等,是后续建立用户画像、用户行为路径等数据产品的基础。 前端的埋点方式主要分为代码埋点、可视化埋点、无埋点三…

前端埋点实现

您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~ 前端埋点实践 介绍1. 实现自定义hook,监测组件2. 收集数据3.前端错误捕捉4. 发送后端保存数据5.收集数据展示总结 介绍 这段时间博主一直在投入…

前端埋点实现及原理分析

正如在宏观介绍的博客中写到的,做用户行为分析的方式有“前端埋点”和“后端埋点”的区分,真好今天敲了一个坤哥整理的“前端埋点”的程序,理解了之后结合demo来简单讲解“前端埋点”如何做。 前端埋点原理图: 如上所示&#xff…

FReLU

论文:https://arxiv.org/pdf/2007.11824.pdf 代码:https://github.com/megvii-model/FunnelAct 概述 卷积神经网络(CNN)在许多视觉识别任务(例如图像分类,目标检测和语义分割)中均达到了最先进…

LFR benchmark在windows操作系统下形成网络详细步骤

研究社交网络的人应该都知道LFR benchmark network吧。但是我从网上找到很多关于LFR的压缩包,里面包含很多.cpp文件,在vs下建工程,把这些文件放进去却怎么也跑不通,真的是很恼火。 今天,终于看到一篇博客,…

神经网络-LFR model

CLDNN[1] 不同的网络结构有不同的优势 CNN擅长减少频率偏移LSTM擅长对时序信号进行建模DNN可以对特征做更高阶的抽象,更容易进行分类 CLDNN依次将CNN/LSTM/DNN进行串联组合成一个新的网络,相当于依次进行频域变化/时域关联/特征抽象,相比于…

CRLF和LF区别

目录: 文章目录 1、什么是CRLF和LF2、为什么要探究CRLF和LF3、三种方式处理的不同4、在Git中如何转换?参考文献 1、什么是CRLF和LF CRLF 是carriagereturnline feed的缩写。中文意思是回车换行。 LF是line feed的缩写,中文意思是换行。 2、…

LFR benchmark 操作步骤

先奉上资源 链接:https://pan.baidu.com/s/1Mm_UwUAhM0ofKXcFbti0YA 提取码:hvp8 复制这段内容后打开百度网盘手机App,操作更方便哦运行操作 在解压后的文件下找到 /benchmark/Debug 文件夹, 在该文件下运行命令行程序&#x…

西克推出LBR/LFR长距离非接触物位/液位传感器

西克推出LBR/LFR长距离非接触物位/液位传感器 在日常的生产过程中,我们可能会遇到一些严苛的工作环境,例如上百米高的筒仓,诸多粉尘的罐内环境,亦或是充满蒸汽或附着物的生产环境;对料位的监控显得更加重要和困难。传…

CRLF和LF

目录: 什么是CRLF和LF为什么要探究CRLF和LF三种方式处理的不同更多参考文献 👁 关注微信公众号:非典型理科男 回复:架构设计 获取 架构设计经典著作 1、什么是CRLF和LF CRLF 是carriagereturnline feed的缩写。中文意思是回车换…

使用Arduino Uno构建一个巡线机器人

使用Arduino Uno构建一个巡线机器人 原文 MX 巡线机器人(LFR: line follower robot)是一种简单的自主引导机器人,它遵循在地面上绘制的线来检测白色表面上的暗线或黑暗表面上的白线。在本教程中,使用 Arduino Uno 和一些易于访问…

网络科学—Windows下生成LFR人工网络数据集的步骤

目录 1 引言 2 步骤 2.1 下载LFR程序包 2.2 解压LFR程序包 2.3 进入cmd程序 2.4 生成LFR网络 1 引言 很多做网络科学研究的学者研究生等都需要经常用到人工网络的数据,最为常用的就是LFR人工网络,下面详细描述了LFR网络的生成方式 2 步骤 2.1 下…

查看gcc编译器版本

我们在windows下DS5中编译时使用GCC交叉编译器,但是在ubuntu时也需要使用GCC编译器,这时最好时保持版本一致,所以就需要查看windows下版本,如下图,在按装的文件夹中找到对应得文件即可。 转载于:https://www.cnblogs.c…

linux下gcc版本切换

今天在linux环境下编译c文件的时候发现库函数居然找不到路径,查了好久都没有找到是什么问题,最后想到的解决办法:把gcc版本切回到linux自带版本 1.查看linux下已安装gcc版本 ls /usr/bin/gcc* 结果如下: 2.手动设置候选版本优先…

linux中gcc版本升级

环境 Linux version 3.10.0-1160.el7.x86_64 (mockbuildkbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) ) #1 SMP Mon Oct 19 16:18:59 UTC 2020 目前gcc版本4.8.5 正文 所需资源可以在gnu安装包下载_开源镜像站-阿里云下载 包括&#x…

Linux升级gcc到最新版本--gcc-9.1.0

Linux升级gcc到最新版本–gcc-9.1.0详细步骤 一、下载gcc最新的源码包–>wget http://ftp.gnu.org/gnu/gcc/gcc-9.1.0/gcc-9.1.0.tar.gz 二、解压缩–>tar -xzvf gcc-9.1.0.tar.gz 三、进入解压缩后目录–>cd gcc-9.1.0 四、运行download_prerequisites脚本&#xff0…

所有Gcc版本对C和C++的支持情况(超详细版本)

在最近接触的新的项目,由于技术使用为C98风格实现,遇到一个问题需要加锁解决,本能反应用lock_guradmutex解决,但是没设置CFLAGS为C11标准,不确定当前gcc编译器默认支持的C和C标准是什么,索性就一把都研究透…

Linux 安装指定版本GCC方法

今天来记录一下如何安装指定版本gcc,因为在linux中有些软件需要指定gcc的版本,所以记录一下还是很有必要的。好了,直接上安装步骤。 第一步:安装默认版本gcc 首先我们需要安装一个gcc,我们使用yum命令来进行安装。 $ y…

linux升级gcc版本详细教程

0.前言 一般linux操作系统默认的gcc版本都比较低,例如centos7系统默认的gcc版本为4.8.5。gcc是从4.7版本开始支持C11的,4.8版本对C11新特性的编译支持还不够完善,因此如果需要更好的体验C11以及以上版本的新特性,需要升级gcc到一个…