前端代码埋点

来源:互联网 发布:应用公园软件下载 编辑:程序博客网 时间:2024/06/09 23:38

网站统计的基本流程

首先,用户的行为会触发浏览器对被统计页面的一个http请求,这里姑且先认为行为就是打开网页。当网页被打开,页面中的埋点JavaScript片段会被执行,用过相关工具的朋友应该知道,一般网站统计工具都会要求用户在网页中加入一小段javascript代码,这个代码片段一般会动态创建一个script标签,并将src指向一个单独的js文件,此时这个单独的js文件会被浏览器请求到并执行,这个js往往就是真正的数据收集脚本。数据收集完成后,js会请求一个后端的数据收集脚本,这个脚本一般是一个伪装成图片的动态脚本程序,可能由phy、Python或其它服务端语言编写,js会将收集到的数据通过http参数的方式传递给后端脚本,后端脚本解析参数并按固定格式记录到访问日志,同时可能会在http响应中给客户端种植一些用于追踪的cookie。

数据收集具体细节

  1. 通过浏览器内置javascript对象收集信息,如页面title(通过document.title)、referrer(上一跳url,通过document.referrer)【referrer 属性可返回载入当前文档的文档的 URL】、用户显示器分辨率(通过windows.screen)、cookie信息(通过document.cookie)等等一些信息。
  2. 创建一个最基本的发送统计的发送函数,用于创建img,发送统计请求到数据采集平台(后台)。详细代码见七埋点实例中的创建img

后端脚本执行阶段

  • (1)解析http请求参数的信息。
  • (2)从服务器(WebServer)中获取一些客户端(前端)无法获取的信息,如访客ip等。
  • (3)将信息按格式写入log。
  • (4)生成一副1×1的空gif图片作为响应内容并将响应头的Content-type设为image/gif。
  • (5)在响应头中通过Set-cookie设置一些需要的cookie信息。

~~~~如果没有跨站跟踪同一用户的需求,可以通过js将cookie种植在被统计站点的域下,如果要全网统一定位,则通过后端脚本种植在服务端域下。

埋点代码

<script type="text/javascript">     var _maq = _maq || [];    _maq.push(['_setAccount', '网站标识']);    (function() {        var ma = document.createElement('script'); ma.type = 'text/javascript'; ma.async = true;        ma.src = ('https:' == document.location.protocol ? 'https://analytics' : 'http://analytics') + '.codinglabs.org/ma.js';        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ma, s);    })();     </script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

前端统计脚本

(function () {    var params = {};    //Document对象数据     if(document) {        params.domain = document.domain || '';         params.url = document.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) {        if(args != '') {            args += '&';        }           args += i + '=' + encodeURIComponent(params[i]);    }       //通过Image对象请求后端脚本     var img = new Image(1, 1);     img.src = '后端脚本地址?' + args;})();
  • 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
  • 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

名词解释

流量的意思包含了很多:页面浏览数(PV)、独立访问者数量(UV)、IP、页面停留时间、页面操作时间、页面访问次数、按钮点击次数、文件下载次数等。

埋点实例脚本

  • 借助新浪IP地址库,显示本地城市名称:
 <script src="http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=js" type="text/ecmascript"></script>     remote_ip_info.country   remote_ip_info.province   remote_ip_info.city
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4
  • 获取客户端IP:
  <script type="text/javascript" src="http://www.coding123.net/getip.ashx?js=1"></script>
  • 1
  • 1
  • 获取用户的访问开始时间、访问结束时间、以及用户与网站的交互时间(当用户在网页无操作时间超过30秒,理解为离开网页),其中无操作包括:鼠标点击、移动、滑轮无操作,键盘无按键操作。
  var start = new Date();                    var strStart = start.getFullYear()+"-"+(start.getMonth()+1)+"-"+start.getDate()+" "+                                          start.getHours()+":"+start.getMinutes()+":"+start.getSeconds();                    var len = 0;                    var end;                    var status = "in";                    var second = 30;                    function revive(){                        if(status == "out"){                        start = new Date();                        status = "in";                        }                        second = 30;                    }                    window.setInterval(function(){                    second -= 1;                        if(0 == second){                            end = new Date();                            len += (end.getTime() - start.getTime())/1000;                            status = "out";                        }                    },1000);                $(‘body‘).click(function(){                    revive();                });                $(‘body‘).mousedown(function(){                    revive();                });                $(‘body‘).mouseup(function(){                    revive();                });                $(‘body‘).mousemove(function(){                    revive();                });                //(Firefox)                $(‘body‘).bind(‘DOMMouseScroll‘, function() {                    revive();                });                //(IE,Google)                $(‘body‘).bind(‘mousewheel‘,function(){                    revive();                });                $(‘body‘).keydown(function(e){                    revive();                });                 $(‘body‘).keyup(function(e){                    revive();                });                 $(‘body‘).keypress(function(e){                    revive();                });                window.onbeforeunload = function(){                   end = new Date();                   var strEnd = end.getFullYear()+"-"+(end.getMonth()+1)+"-"+end.getDate()+" "+                                        end.getHours()+":"+end.getMinutes()+":"+end.getSeconds();                   len += (end.getTime() - start.getTime())/1000;                    var img = new Image();                   img.src = contextPath + "behavior?stayTime=" + len + "&strStart" + strStart + "&lastDate=" + strEnd;                };
  • 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
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 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
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 获取点击按钮
  <a onclick="return getid(this.id)"> 按钮</a>            function getid(id) {                var img = new Image();                img.src = contextPath + "button?id=" + id;            }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 获取搜索来源

    判断从哪个搜索工具找到你的网站,document.referrer(上级URL),这个可以获取到你上级页面,如果看到上级URL里面包含baidu,就可以粗略的判断是从百度访问的页面。

  • 创建img

   function sendUrl(url) {                let img = new Image();  // 创建一个img对象                let key = 'project_log_' // 为本次数据请求创建一个唯一id                    + Math.floor(Math.random() * 2147483648).toString(36);                 window[key] = img;   // 用一个数组维护img对象                img.onload = img.onerror = img.onabort = function () {                    img.onload = img.onerror = img.onabort = null;  // 清除img元素                    window[key] = null;                    img = null;                  };                img.src = url;  // img对象赋值url后自动发送请求,无需插入到页面元素中去            }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14