前端埋点实现及原理分析

article/2025/10/8 9:01:11

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

前端埋点原理图:

在这里插入图片描述
如上所示,从broswer到page,再到javascript以及后端backend,浏览器返回正常程序运行结果,本地文件中返回最终的log,这很像是在用户程序中埋下了一段“暗代码”,无形之中“窃取”了用户的行为信息,淘宝、网易等都有这样的功能。
可以参考google做的Google Analysis这块产品)

步骤:

  • 埋点阶段
  • 数据收集阶段
  • 后端处理阶段

如上,针对“前端埋点”,主要分为这么三部,对应到上面的原理图,步骤一即(create script element),步骤二即collect client data,步骤三即backend和log.

下面,分别按照上述三步来展示代码:

埋点阶段

<script type="text/javascript">var _maq = _maq || [];_maq.push(['_setAccount', 'uuid']);(function () {var ma = document.createElement('script');ma.type = 'text/javascript';ma.async = true;ma.src = "http://localhost:8091/data/js/ma.js";var s = document.getElementsByTagName('script')[0];s.parentNode.insertBefore(ma, s);})();
</script>

这里是正常的jsp、html页面,在页面的下端,往往插入一小段js代码,即我们的“埋点”,如上所示,“埋点”中的全局数组,用于收集该页面中需要被回传的用户行为,比如:域名、ip、url、搜索的内容、常按的按钮名称……,(这里暂时通过‘_setAccount’来传递了一个值为‘vincent’的用户名)

之后匿名的js函数,是埋点代码的重中之重,如上代码所示,在Dom节点添加名为‘script’的元素,设置"ma.async = true",表示让其异步执行,并将其src属性指定为一个单独的js文件(将ma.js引入进来),最终将该element插到当前Dom树上。而这个过程最终的目的即请求并执行上述的ma.js文件。

数据收集阶段

(function () {var params = {};//Document对象数据if (document) {params.domain = document.domain || ''; //获取域名params.url = document.URL || '';       //当前Url地址params.title = document.title || '';params.referrer = document.referrer || '';  //上一跳路径}//Window对象数据if (window && window.screen) {params.sh = window.screen.height || 0;    //获取显示屏信息params.sw = window.screen.width || 0;params.cd = window.screen.colorDepth || 0;}//navigator对象数据if (navigator) {params.lang = navigator.language || '';    //获取所用语言种类}//解析_maq配置if (_maq) {for (var i in _maq) {                      //获取埋点阶段,传递过来的用户行为switch (_maq[i][0]) {case '_setAccount':params.account = _maq[i][1];break;default:break;}}}//拼接参数串var args = '';for (var i in params) {// alert(i);if (args != '') {args += '&';}args += i + '=' + params[i];           //将所有获取到的信息进行拼接}//通过伪装成Image对象,请求后端脚本var img = new Image(1, 1);var src = 'http://localhost:8091/data/dataCollection/log.gif?args=' + encodeURIComponent(args);alert("请求到的后端脚本为" + src);img.src = src;
})();

如上代码所示,是ma.js文件中的代码,如上我做的注释,可以将这个过程分为3步骤;

  1. 解析、获取用户各种信息,如上:1.通过dom树,获取到的url,域名,上一跳信息;2.通过windows,获取到的显视屏的分辨率、长宽(前两类通过内置的js对象获取);3.通过_maq全局数组,获取埋点时埋下的用户行为数据。
  2. 将上步的用户信息按特定格式拼接,装到args这个参数中。
  3. 伪装成图片,请求到后端controller中,并将args作为http request参数传入,做后端分析。

之所以使用图片请求后端controller而不是ajax直接访问,原因在于ajax不能跨域请求,ma.js和后端分析的代码可能不在相同的域内,ajax做不到,而将image对象的src属性指向后端脚本并携带参数,就轻松实现了跨域请求。

后端处理阶段

@Controller
@RequestMapping("/dataCollection")
public class DataCollection {@RequestMapping(value = "log.gif")public void analysis(String args, HttpServletResponse response) throws IOException {System.out.println(args);//日志收集 response.setHeader("Pragma", "No-cache");response.setHeader("Cache-Control", "no-cache");response.setDateHeader("Expires", 0);response.setContentType("image/gif");OutputStream out = response.getOutputStream();BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);ImageIO.write(image, "gif", out);out.flush();}
}

如上所示, 通过解析http request中的参数,即将在前端获取到的用户信息拿到了后端,这个为了验证,将其打印到控制台,接下来就是做日志收集工作了,到此前端获取用户信息已经完成。之后,生成一副1×1的空gif图片作为响应内容并将响应头的Content-type设为image/gif,返回到前端代码中。

如图,是在控制台我拿到的用户信息:
在这里插入图片描述
至此,前端埋点的实现以及原理就ok了,包括Google Analytics也是这么个原理来做的。目前我跑的程序已经收集到了用户的行为信息,但是存在一个问题就是用户删除cookie信息,比如清楚浏览器缓存,会造成收集到的数据比实际访问的行为数据要多得多,这个问题接下来会继续深入研究。

这个程序已经上传到我的GitHub上,感兴趣的朋友可以去下载,另外感谢网络上的关于这块的资料贡献者,能让我对行为分析有深入的认识,多谢。
github地址:git@github.com:zhangzhenhua92/datacollection.git


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

相关文章

FReLU

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

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

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

神经网络-LFR model

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

CRLF和LF区别

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

LFR benchmark 操作步骤

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

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

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

CRLF和LF

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

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

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

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

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

查看gcc编译器版本

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

linux下gcc版本切换

今天在linux环境下编译c文件的时候发现库函数居然找不到路径&#xff0c;查了好久都没有找到是什么问题&#xff0c;最后想到的解决办法&#xff1a;把gcc版本切回到linux自带版本 1.查看linux下已安装gcc版本 ls /usr/bin/gcc* 结果如下&#xff1a; 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++的支持情况(超详细版本)

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

Linux 安装指定版本GCC方法

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

linux升级gcc版本详细教程

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

ubuntu20.04查看gcc版本以及各版本切换

1、查看自己当前的gcc版本 gcc -v通过下图的最后一行可以得到&#xff0c;这里电脑当前gcc的版本是 7.5.0 查看Eigen版本&#xff1a; pkg-config --modversion eigen32.安装另一个版本gcc 这里安装的是gcc-9&#xff1a; sudo add-apt-repository ppa:ubuntu-toolchain-r…

最新:斐讯K3千兆无线路由器刷官改版固件的详细图文教程

2018年1月31日更新&#xff1a;本教程已经同步增添Phitools 作者最新修改的固件以便支持 K3_V21.6.12.66 版刷机。 如果喜欢折腾的话可以刷LEDE固件&#xff0c;刷机方法看&#xff1a;[图文教程] 斐讯K3金/银色版路由器免拆机通用刷机教程 此前蓝点网已经发布了借助恩山论坛开…

斐讯k2刷不死breed K2 22.5.11.14

[k2] 斐讯K2 22.5.11.14 A5 原厂固件 刷breed刷官方固件定制版方法 这个是我刷机之前备份的&#xff0c;有用的拿去。 首先是刷breed&#xff0c;按照abccba94大神的终极方法刷入成功&#xff0c;参考【刷机必读】斐讯K2刷breed的安全方法及开源一键刷机脚本 终极的不行&…