采集接口要做的约定

{
    "header":{ // HTTP 头部
        "X-Device-Id":" 550e8400-e29b-41d4-a716-446655440000", //设备ID,用来区分用户设备
        "X-Source-Url":"https://www.baidu.com/", //源地址,关联用户的整个操作流程,用于用户行为路径分析,例如登录,到首页,进入商品详情,退出这一整个完整的路径
        "X-Current-Url":"", //当前地址,用户行为发生的页面
        "X-User-Id":"",//用户ID,统计登录用户行为
    },
    "body":[{ // HTTP Body体
        "PageSessionID":"", //页面标识ID,用来区分页面事件,例如加载和离开我们会发两个事件,这个标识可以让我们知道这个事件是发生在一个页面上
        "Event":"loaded", //事件类型,区分用户行为事件
        "PageTitle":  "埋点测试页",  //页面标题,直观看到用户访问页面
        "CurrentTime":  “1517798922201”,  //事件发生的时间
        "ExtraInfo":  {
         }    //扩展字段,对具体业务分析的传参
    }]
}

以上就是我们现在约定好了的通用的事件采集的接口,所传的参数基本上会根据采集事件的不同而发生变化。但是在用户的整一个访问行为中,用户的设备是不会变化的,如果你想采集设备信息可以重新约定一个接口,在整个采集开始之前发送设备信息,这样可以避免在事件采集接口上重复采集固定数据。

{
    "header":{ // HTTP 头部
          "X-Device-Id"  :"550e8400-e29b-41d4-a716-446655440000"  ,      //  设备id
    },
    "body":{ // HTTP Body体
              "DeviceType":  "web" ,   //设备类型
             "ScreenWide"  :  768 , //  屏幕宽
             "ScreenHigh":  1366 , //  屏幕高
             "Language":    "zh-cn"  //语言
    }
}

业务方通过什么方式来调用我们的采集脚本
埋点应该让调用的业务方,尽可能少有工作量
采用的方案是让业务方在代码里通过 script 脚本来引用我们的 SDK

(function() {
            var collect = document.createElement('script');
            collect.type = 'text/javascript';
            collect.async = true;
            collect.src =  'http://collect.trc.com/index.js';
            var s = document.getElementsByTagName('script')[0];
            s.parentNode.insertBefore(collect, s);
    })();


//用户自定义要进行无埋点采集的元素,如果不进行无埋点采集,可以不配置
 var _XT = [];
  _XT.push(['Target','div']);

手动埋点:SDK
如果业务方需要采集更多业务定制的数据,可以调用我们暴露出的方法进行采集

//自定义事件
  sdk.dispatch('customEvent',{extraInfo:'自定义事件的额外信息'})

单页面应用:采集数据
window 的 history 对象 提供了两个方法,能够无刷新的修改用户的浏览记录,pushSate,和 replaceState,区别的 pushState 在用户访问页面后面添加一个访问记录, replaceState 则是直接替换了当前访问记录,所以我们只要改写 history 的方法,在方法执行前执行我们的采集方法就能实现对单页面应用的页面跳转事件的采集了

collect = {}
    collect.onPushStateCallback : function(){}  // 自定义的采集方法

    (function(history){
        var replaceState = history.replaceState;   // 存储原生 replaceState
        history.replaceState = function(state, param) {     // 改写 replaceState
           var url = arguments[2];
           if (typeof collect.onPushStateCallback == "function") {
                 collect.onPushStateCallback({state: state, param: param, url: url});   //自定义的采集行为方法
           }
           return replaceState.apply(history, arguments);    // 调用原生的 replaceState
        };
     })(window.history);

判断是否是首页刷新

isIndexPage () {
      let url = location.href
      let isIndex = false
      isIndex = url.indexOf(this.defaultConfig.indexPageFlag) + 1 > 0
      this.qlog.log('是否是首页: ', isIndex)
      return isIndex
    }

设置页面的访问记录

setPrePageNameLogs () {
    let tempArry = [].concat(this.getStorageValue('prePageNameLogs'));
    /* 如果是当前页刷新, 则不记录 */
    if (tempArry[tempArry.length - 1] !== this._data.pageName) {
      tempArry.push(this._data.pageName)
      /* 只保留近的10条记录 */
      tempArry = tempArry.slice(-10)
    }

    this._data.prePageNameLogs = tempArry
    this.setStorageValue('prePageNameLogs', tempArry)
    }

性能监控 (js中的performance)

let timing = performance.timing,
     start = timing.navigationStart,
     dnsTime = 0,
     tcpTime = 0,
     firstPaintTime = 0,
     domRenderTime = 0,
     loadTime = 0;
//DNS解析时间
dnsTime = timing.domainLookupEnd - timing.domainLookupStart;
//TCP建立时间
tcpTime = timing.connectEnd - timing.connectStart;
//首屏时间
firstPaintTime = timing.responseStart - start;
//dom渲染完成时间
domRenderTime = timing.domContentLoadedEventEnd - start;
//页面onload时间
loadTime = timing.loadEventEnd - start;