简单介绍
不再需要开发人员在业务代码中手动植入埋点上报请求,而是通过 sdk 自动分析上报所有的有效用户行为信息数据,更方便,更准确。
技术方案
规范定义
1.需要统计哪些数据。
页面的 pv、uv、设备型号、时间段、特别元素的点击次数
2.需要怎么定义这些数据格式。
首次进入(pipe.visitor
)、进入(pipe.enter
)、离开(pipe.leave
)、点击(event.click
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| { utmId: "渠道号.站点号.频道号.页面号", vid: "用户唯一的唯一编号" logs:[ { key: "event.click", time: 121212121, tags: ["ab","c"], extra: { path: "BODY[0]/.banner/IMG[0]", content: "元素所包含的内容", } } ] }
|
3.如何来实现。
1.解析 url 来获取页面的 utmId
2.sha1 生成随机 id 存 localStorage 用作唯一编号 3.事件监听获取点击元素,通过 xpath 规则获取元素路径
代码实现
封装 SDK 对外只暴露 UTM 对象,防止变量污染。
1.utmId 的获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
UTM.utmID = function (id) { if (!id) { if (UTM._utmID) { return UTM._utmID; } var utmParts = UTM.getQuery("utm").split(".", 4); utmParts.length = 4; utmParts[1] = utmParts[1] || location.hostname.replace(/\./g, "-"); var path = location.href .replace(/^.*?:\/\/[^/]*/, "") .replace(/\?.*#/i, "#") .replace(/\?.*$/i, "") .replace(/\./g, "-") .replace(/^\//, ""); var slash = path.indexOf("/"); utmParts[2] = utmParts[2] || path.slice(0, slash); utmParts[3] = utmParts[3] || path.slice(slash + 1); return (UTM._utmID = utmParts.join(".")); } UTM._utmID = id; };
|
2.获取元素唯一路径
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
UTM.utmPath = function (node) { if (node.id && document.getElementById(node.id) === node) { return "#" + node.id; } if (node.className && document.getElementsByClassName) { var classNames = node.className.split(/\s+/, 1); for (var i = 0; i < classNames.length; i++) { if (document.getElementsByClassName(classNames[i]).length === 1) { return "." + classNames[i]; } } } if (document.getElementsByTagName(node.tagName).length === 1) { return node.tagName; } var path = node.id ? "#" + node.id : node.className ? "." + node.className.replace(/\s.*$/, "") : node.tagName; if (node.parentNode) { var index = 0; for (var n = node.parentNode.firstChild; n != node; n = n.nextSibling) { if (n.tagName == node.tagName) { index++; } } return UTM.utmPath(node.parentNode) + "/" + path + "[" + index + "]"; } return path; };
|
3.埋点数据上报
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
UTM.utmFlush = function (useBeacon) { var utm = UTM.utmID(); var vid = UTM.utmVID(); var logs = UTM._utmLogs;
while (logs.length) { var url = "http://xxx.com?utm=" + encodeURIComponent(utm); if (vid) url += "&vid=" + encodeURIComponent(vid); url += "&logs=[" + logs.shift(); while (logs.length && url.length + logs[0].length < 7206) { url += "," + logs.shift(); } url += "]"; url = url.replace(/\n|\r|\t/g, ""); if (useBeacon === true) { if (navigator.sendBeacon) { navigator.sendBeacon(url); } else { var xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.send(null); } } else { var script = document.createElement("script"); script.async = true; script.setAttribute("crossorigin", "anonymous"); script.onload = script.onreadystatechange = function () { if ( !script.readyState || script.readyState === "loaded" || script.readyState === "complete" ) { script.onload = script.onreadystatechange = null; script.parentNode.removeChild(script); } }; script.src = url; var firstScript = document.getElementsByTagName("script")[0]; firstScript.parentNode.insertBefore(script, firstScript); } } };
|
4.SDK 初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
UTM.utmInit = function () { UTM.utm("pipe.enter", {});
document.addEventListener( "click", function (e) { if (e.isTrusted !== false) { UTM.utm("event.click", { path: UTM.utmPath(e.target), content: UTM.utmContent(e.target), }); } }, true );
window.addEventListener( "unload", function (e) { UTM.utm("pipe.leave"); UTM.utmFlush(true); }, false );
UTM.initSPA(); };
|
最后
以上所附代码片段仅供参考,所提供的是一种设计思路。很多工具类方法,以及一些细节处理都没有展开。比如:需要获取多少设备型号信息、单页应用的数据上报规则、以及一些业务适配、一些高级功能用法拓展等等。
在企业中,可能光开发一个无痕埋点 SDK 还远远不够,需要搭建一个数据分析系统,能够处理巨大的数据量,以及搭建一个数据可视化系统,将基础数据展示,方便业务开发直接使用。同样的可能还需要做一个圈选功能,类似于 gio 的圈选功能,能够可视化的定位需要统计的元素。
目前很多社区方案都十分成熟可以借鉴参考,同时还是要考虑应用的业务场景,考虑当前的流量是否可以做全量上报数据方案或者是做后置数据上报方案,再或者是结合上报。感谢大佬们阅读到此,不足之处请多多包涵。