app嵌入的H5页面的数据埋点总结

好久没写博客了,大半年时间花费在了许多杂事上。

最近1个月专门为H5页面的app开发了一些埋点功能,主要是考虑到以后的可复制性和通用型,由于不是前端开发出身,相对来说还是比较简陋的。

正题开始:H5页面的埋点主要涉及到的元素有a标签,button按钮,以及form表单的提交。

目前实现的功能基本还都是代码埋点的方式,但是相对来说比较简洁了,我这里主要是针对a标签和button的事件埋点。

第一个js脚本 bigdataIndex.js

var _qjmap = _qjmap || [];
var _bigdataDomain = "http://localhost:8082/"
_qjmap.push(['tenantCode', 'xxxxx000001']);

(function () {

    //监控a标签的单击事件
    var a = document.getElementsByTagName("a");
    for(var i =0; i<a.length; i++){
        a[i].onclick = (function(i){
            return function(){
                var data = this.getAttribute('data-bigdata');
                var href = this.getAttribute('href');

                if(data){

                    var prevEvent = sessionStorage.getItem("event") || '';
                    sessionStorage.setItem("prevEvent",prevEvent);

                    if(data.indexOf(':') != -1){
                        var event = data.split(':')[0] || '';
                        var eventData = data.split(':')[1]|| '';
                        sessionStorage.setItem("event", event);
                        sessionStorage.setItem("eventData", eventData);
                    }else {
                        sessionStorage.setItem("event", data);
                    }
                }
                if(href){
                    sessionStorage.setItem('href', href);
                }
                send();
            }
        })(i);
    }

    function send(){
        var ma = document.createElement('script');
        ma.type = 'text/javascript';
        ma.async = true;
        ma.src = _bigdataDomain + "js/qjdata.js?v=1";
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(ma, s);
    }


    //在按钮事件中调用该方法
    function btnEventSend(event,data){
        sessionStorage.setItem("prevEvent",sessionStorage.getItem("prevEvent"));
        sessionStorage.setItem("event", event);
        sessionStorage.setItem("eventData", data);
        send();
    }

})();


//为button时候,手工触发
function bigdataBtnEventSend(event, data){
    sessionStorage.setItem("prevEvent",sessionStorage.getItem("prevEvent"));
    sessionStorage.setItem("event", event);
    sessionStorage.setItem("eventData", data);
    var ma = document.createElement('script');
    ma.type = 'text/javascript';
    ma.async = true;
    ma.src = _bigdataDomain + "js/qjdata.js?v=1";
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(ma, s);
}

说明:

_qjmap为全局变量:添加的tenantCode为租户的id,如果统计多个应用,可以通过这个字段来区分。
_bigdataDomain为第一个js脚本下载第二个js脚本的域名地址。

接下来在一个闭包函数中监听了a标签的单击事件, 如果触发,则获取a标签data-bigdata属性、href属性,
并且从sessionStorage中获取对应的事件,保存到sessionStorage中作为上个事件,以便下个事件获取。

如果该事件带有具体的数据,则必须使用冒号放到事件类型后面,方便后面的分拆保存。
例如:用户点击商品列表中的某个商品,跳转到商品详情页面中。
则设置a标签的属性为 <a href="item/123456.htm" data-bigdata="viewGoods:123456">苹果</a>
经过如上设置,在该页面中嵌入上面的bigdataIndex.js,则event为viewGoods, eventData为123456(这里123456假设为商品的id)。

接下来最重要的就是send()方法:
    function send(){
        var ma = document.createElement('script');
        ma.type = 'text/javascript';
        ma.async = true;
        ma.src = _bigdataDomain + "js/qjdata.js?v=1";
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(ma, s);
    }

该方法中动态创建一个脚本,并且从远程服务器上下载qjdata.js文件加载到页面中,此处使用的是异步加载的方式。

qjdata.js

(function(){

    function getOsInfo() { // 获取当前操作系统
        var os;
        if (navigator.userAgent.indexOf('Android') > -1 || navigator.userAgent.indexOf('Linux') > -1) {
            os = 'Android';
        } else if (navigator.userAgent.indexOf('iPhone') > -1) {
            os = 'IOS';
        } else if (navigator.userAgent.indexOf('Windows Phone') > -1) {
            os = 'WP';
        } else {
            os = 'none';  //未知
        }
        return os;
    }

    function getOSVersion() { // 获取操作系统版本
        var OSVision = '1.0';
        var u = navigator.userAgent;
        var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //Android
        var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
        if (isAndroid) {
            OSVision = navigator.userAgent.split(';')[1].match(/\d+\.\d+/g)[0];
        }
        if (isIOS) {
            OSVision = navigator.userAgent.split(';')[1].match(/(\d+)_(\d+)_?(\d+)?/)[0];
        }
        return OSVision;
    }

    function getDeviceType() { // 获取设备类型
        var deviceType;
        var sUserAgent = navigator.userAgent.toLowerCase();
        var bIsIpad = sUserAgent.match(/(ipad)/i) == "ipad";
        var bIsIphoneOs = sUserAgent.match(/iphone os/i) == "iphone os";
        var bIsMidp = sUserAgent.match(/midp/i) == "midp";
        var bIsUc7 = sUserAgent.match(/rv:1.2.3.4/i) == "rv:1.2.3.4";
        var bIsUc = sUserAgent.match(/ucweb/i) == "ucweb";
        var bIsAndroid = sUserAgent.match(/android/i) == "android";
        var bIsCE = sUserAgent.match(/windows ce/i) == "windows ce";
        var bIsWM = sUserAgent.match(/windows mobile/i) == "windows mobile";

        if (!(bIsIpad || bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM)) {
            deviceType = 'PC'; //pc
        } else if (bIsIphoneOs || bIsMidp || bIsUc7 || bIsUc || bIsAndroid || bIsCE || bIsWM) {
            deviceType = 'phone'; //phone
        } else if (bIsIpad) {
            deviceType = 'ipad'; //ipad
        } else {
            deviceType = 'none';  //未知
        }
        return deviceType;
    }

    function getOrientationStatus() { // 获取横竖屏状态
        var orientationStatus;
        if (window.screen.orientation.angle == 180 || window.screen.orientation.angle == 0) { // 竖屏
            orientationStatus = '竖屏';
        }
        if (window.screen.orientation.angle == 90 || window.screen.orientation.angle == -90) { // 横屏
            orientationStatus = '横屏';
        }
        return orientationStatus;
    }

    function getNetWork() { // 获取网络状态
        var netWork;
        switch (navigator.connection.effectiveType) {
            case 'wifi':
                netWork = 'wifi'; // wifi
                break;
            case '5g':
                netWork = '5G'; // 5g
                break;
            case '4g':
                netWork = '4G'; // 4g
                break;
            case '2g':
                netWork = '2G'; // 2g
                break;
            case  '3g':
                netWork = '3G'; // 3g
                break;
            case  'ethernet':
                netWork = 'ethernet'; // 有线
                break;
            case  'default':
                netWork = 'none'; // 未知
                break;
        }
        return netWork;
    }

    //生成唯一Id
    function generateUUID() {
        var d = new Date().getTime();
        if (window.performance && typeof window.performance.now === "function") {
            d += performance.now(); //use high-precision timer if available
        }
        var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
        });
        return uuid;
    }


    //判断用户是否存在,不存在则生成唯一号
    function getUUID() {
        var uuid = localStorage.getItem("bigdata_uuid");
        if(uuid == '' || uuid == null){
            uuid = generateUUID();
            localStorage.setItem("bigdata_uuid", uuid);
        }
        return uuid;
    }

    //获取cookie
    function getCookie(sName)
    {
        var aCookie = document.cookie.split("; ");
        var returnValue = "";
        for (var i=0; i < aCookie.length; i++)
        {
            var key = sName + '=';
            if(aCookie[i].indexOf(key) != -1){
                returnValue = unescape(aCookie[i].substr(sName.length + 1));
            }
        }
        return returnValue;
    }

    function setCookie(name,value)
    {
        var Days = 30;
        var exp = new Date();
        exp.setTime(exp.getTime() + Days*24*60*60*1000);
        document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();
    }

    function clearCookie(name){
        setCookie(name,'');
    }

    //页面离开时触发
    // window.onbeforeunload = function(){
    //     params.intime = localStorage.getItem("bigdata_intime");
    //     params.duration = getDuration();
    //     params.outtime =  Date.now();
    // }

    //记录的参数值
    var params = {};
    params.osInfo = getOsInfo();
    params.osVersion = getOSVersion();
    params.deviceType = getDeviceType();
    params.webType = getNetWork();
    params.orientationStatus = getOrientationStatus();
    params.deviceId = getUUID();
    params.actionTime = Date.now();
    var intime = sessionStorage.getItem("bigdata_intime");
    params.previousUrl_intime = intime || '' ;
    params.duration = intime == null ? 0 : Date.now() - intime;
    sessionStorage.setItem("bigdata_intime", Date.now().toString());


    params.event = sessionStorage.getItem("event");
    params.preEvent = sessionStorage.getItem("prevEvent");
    params.eventData = sessionStorage.getItem("eventData");

    sessionStorage.removeItem("eventData");
    sessionStorage.removeItem('href');
    params.loginName = getCookie("_mall_newMobile_username");
    params.userCode = getCookie("userId");
    params.targetUrl = sessionStorage.getItem('href');
    // params.phoneType = getPhoneTypeAndVersion().split("#")[0];
    // params.phoneVersion = getPhoneTypeAndVersion().split("#")[1];


    //document对象元素
    if(document){
        params.currUrl = document.URL || '';             //当前URL地址
        params.prevUrl = document.referrer || '';     //上一路径

        params.loginIp = document.domain || '';         //获取域名
        params.title = document.title || '';        //标题
    }

    //window对象元素
    if(window && window.screen){
        params.height = window.screen.height || 0;  //获取显示屏信息
        params.width = window.screen.width || 0;
        params.colorDepth = window.screen.colorDepth || 0;
    }

    //navigator对象数据
    if(navigator){

        // var agent = navigator.userAgent.toLowerCase();
        // console.log(agent);
        params.lang = navigator.language || '';  //获取语言的种类
        if(navigator.geolocation) {
            params.longitude = 123;
            params.latitude = 345;
        }
    }

    //解析_qjmap配置
    if(_qjmap){
        for(var i in _qjmap){

            console.log(_qjmap[i]);

            switch (_qjmap[i][0]){
                case 'tenantCode':
                    params.tenantCode = _qjmap[i][1];
                    break;
                default:
                    break;
            }
        }
    }
    
    

    //拼接字符串
    var args = '';
    for(var i in params){
        if(args != ''){
            args += '\x01';
        }
        var p = params[i];
        if(p != null ){
            p = p.toString().replace(new RegExp("=",'g'),"%3D");
        }
        args += i + '=' + p;  //将所有获取到的信息进行拼接
    }

    //通过伪装成Image对象,请求后端脚本
    var img = new Image(1, 1);
    var src = 'http://localhost:8082/bigdata/qjdata.gif?args=' + encodeURIComponent(args);
    // alert("请求到的后端脚本为" + src);
    img.src = src;

})();


猜你喜欢

转载自www.cnblogs.com/30go/p/10445516.html
今日推荐