首页 > 其他分享 >前端埋点数据上传方式

前端埋点数据上传方式

时间:2024-02-23 17:48:31浏览次数:24  
标签:url 前端 buryingPoint sendBeacon error 埋点 上传 页面

数据埋点

  • 数据采集领域的术语,指的是针对用户行为或特定事件进行捕获、处理和发送的相关技术及其实施过程,是对特定事件或者用户行为的数据监控和数据上传。

数据类型

  • 我们从三个维度出发去监控一个项目,即系统所面向的某一个主体,系统单个局部面向使用不同使用主体的差异的情况监控,系统面向运行过程的总体统筹监控这三个方面;也就是用户的行为,页面的性能,产品的异常。

从而我们可以划分三个类别出来:

1、数据监控(涉及用户行为及其相应的事件)
2、性能监控(涉及页面的性能及渲染交互)
3、异常监控(涉及产品系统的运行时异常)

同时我们可以给出一个大致的数据结构范围:

pv:页面访问量
uv:用户访问量
关于用户的自定义事件
关于页面性能加载数据
报错的异常信息

前端埋点方式

了解了怎样前端埋点的相关概念,下面说说埋点有哪些方式,也就是可以使用哪些方式来做埋点的数据监控。

一、 XMLHttpRequest

这种使用方式其实就是约定一个接口,然后通过提交请求去进行数据上报的,如:

function buryingPoint(data) {
  return new Promise((resolve, reject) => {
    // 创建XMLHttpRequest
    const xhr = new XMLHttpRequest();
    // 定义请求接口
    xhr.open("post", '/buryingPoint', true);
    // 发送数据
    xhr.send(data);
  });
}
let info = {}
buryingPoint(info) // 这样就成功上报了info的对象

当我们去调用这个buryingPoint方法时,也就将数据进行了服务端的上报了。
但是,这种传统方式的请求埋点,一般会存在跨域的风险,并且他必须是同步的,否则会容易中断请求。

通过以传统的请求方式进行数据埋点我们可以看出,实现数据上报并不强调前后端的交互的,因此我们也可以通过一些支持跨域的标签去实现数据上报功能。如:

let a = document.createElement('script')
a.src = 'https://www.test.com/web/buryingPoint/test.js?test=123'
document.body.appendChild(a)
  • 创建一个script标签,src地址后面带上我们需要传递的数据,并将这个标签挂载中页面,这样就实现script+link方式的数据上报。
  • 使用script标签还有一个好处就是,它是兼容的,可以适应不同的浏览器。
  • 但是,这种方式也有缺点,那就是需要挂载到页面上,而反复操作dom会造成页面性能受影响,并且载入js/css资源还会阻塞页面渲染,影响用户体验,频繁上报是不适合这种方式的。

三、 img

不同于script标签,使用img标签的好处是,无需挂载到页面上,反复操作dom;而且img的加载不会阻塞html的解析,img加载后并不渲染,它需要等待Render Tree生成完后才和Render Tree一起渲染出来。

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

如:

function buryingPoint(src) {
    var img = document.createElement("img");
    img.src = src;
}
buryingPoint('https://www.test.com/web/buryingPoint/test.gif?test=123')

我们除了img标签还可以使用new image(),设置其src之后就可以直接请求图片。

四、 Navigator.sendBeacon

Navigator.sendBeacon是目前通用的埋点上报方案,Navigator.

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

过去,为了解决这个问题,统计和诊断代码通常要在

  • 发起一个同步 XMLHttpRequest 来发送数据。
  • 创建一个 元素并设置 src,大部分用户代理会延迟卸载(unload)文档以加载图像。
  • 创建一个几秒的 no-op 循环。

上述的所有方法都会迫使用户代理延迟卸载文档,并使得下一个导航出现的更晚。下一个页面对于这种较差的载入表现无能为力。

这就是 sendBeacon() 方法存在的意义。使用 sendBeacon() 方法会使用户代理在有机会时异步地向服务器发送数据,同时不会延迟页面的卸载或影响下一导航的载入性能
这意味着:

  1. 数据发送是可靠的。
  2. 数据异步传输。
  3. 不影响下一导航的载入。
    数据是通过 HTTP POST 请求发送的。

如:

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

buryingPoint('https://www.test.com/web/buryingPoint',{time: Date.now()})

目前最合适的数据上传方案是navigator.sendBeacon,不仅是异步的,而且不受同域限制,而且作为浏览器的任务,因此可以保证会把数据发出去,不影响页面卸载。

常见前端埋点

列举一些常见的前端埋点:

1、点击触发埋点

绑定用户行为触发的点击事件,当点击目标元素,触发埋点的数据上报。

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

2、内容可见埋点

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

// 可见性发生变化后的回调 
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);

3、页面停留时间上报埋点

路由文件中,初始化一个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()
     }
})

4、错误监听埋点

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

//  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: '请求错误异常' })
  }
);

标签:url,前端,buryingPoint,sendBeacon,error,埋点,上传,页面
From: https://www.cnblogs.com/lyly96720/p/18030042

相关文章

  • 前端调试断点方面
    前端调试断点方面目录前端调试断点方面前端报错出了问题debugger前端报错出了问题后端没问题但页面显示不是预想的样式,出现问题,F12进入Network找哪一个请求出了问题,找到那一个请求:然后去前端全局查找ctrl+shift+R找到import的就是引入使用此方法的地方然后看......
  • 资深前端面试资料
    Chrome内核Chrome浏览器采用了Blink渲染引擎,Blink渲染引擎是基于WebKit开发的一个开源渲染引擎。在Chrome浏览器中,除了Blink渲染引擎外,还包括V8JavaScript引擎、Blink应用层、Chrome内置PDF阅读器等组件。Blink渲染引擎是Google在2013年从WebKit中分支......
  • 腾讯云Linux服务器 前端Nginx+后端 项目部署
    一、前端项目部署1.安装nginx服务器:在root目录下创建services文件并下载nginx源文件【nginx-1.21.6.tar.gz】 建议尽量选择稳定版本下载  nginx官网下载地址​​​​cd/rootmkdirservicescdservicescurl-onginx-1.21.6.tar.gzhttp://nginx.org/download/......
  • vue前端引用Jquery完成复选框多选
    vue2前端引用Jquery完成复选框多选通常我们使用element-ui中el-table的多选模板完成列表的多选,但是有时需要把表格进行拆分,此时仅凭element-ui中的控件可能无法实现拆分后的多选。由于vue是JavaScript的前端框架,所以我考虑使用js来实现。jQuery作为JavaScript的补充和扩展,可以更......
  • flask上传图片
       运行pythonmain.py 访问 http://127.0.0.1:8987/upimg  main.py#coding:utf-8fromflaskimportFlask,render_template,request,redirect,url_for,make_response,jsonifyfromwerkzeug.utilsimportsecure_filenameimporto......
  • 前端 html 一个元素padding-right,不起作用?毫无反应?padding right 无效
    有没有宝子,开发html,给一个父元素padding-right,子元素却毫无反应,万分捉急,在线等,急!我知道你着急,但是你先别急我会在这里娓娓道来,带你走上一个新的技术台阶1、一段基础代码代码如下:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"......
  • S3服务器上传问题
    客户S3环境有升级变迁,然后之前上传文件服务器出现异常问题生产环境S3服务器文件上传异常原因及解决方案:上传文件-异常信息如下:com.amazonaws.SdkClientException:Unabletoverifyintegrityofdataupload.Clientcalculatedcontenthash(contentMD5:EWsFdgDklAxX7zec1......
  • 前端必学-40个精选案例实战-案例8-仿京东导航条触碰下拉效果
    导航条触碰下拉效果(理解鼠标浮动伪类、链接激活伪类)<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewpor......
  • 前端必学-40个精选案例实战-案例7-仿爱奇艺视频首页新片预告实战
    仿爱奇艺视频首页新片预告实战案例第一步:案例图片圆角制作、图片资源:代码:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname......
  • 前端处理后端返回datetime类型 格式转换
    有时候后端使用的字段为datetime,接口返回数据会变成/Date(1708311728230+0800)/这种,这时候就需要去转换一下格式functionconvertDateString(dateString){vartimestamp=parseInt(dateString.match(/\d+/)[0]);vartimezoneOffset=parseInt(dateString.match(/[......