百度统计、谷歌统计原理以及自定义统计源码

前端埋点原理图

在这里插入图片描述
如上所示,从broswer到page,再到javascript以及后端backend,浏览器返回正常程序运行结果,本地文件中返回最终的log

步骤:

  • (一)埋点阶段
  • (二)数据收集阶段
  • (三)后端处理阶段

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

埋点

html的script中添加节点

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

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

去引用的ma.js

(function (win) {

    win.lc = {}
    lc.trackInfo = function (paramsArr) {
        console.log('paramsArr1==>', paramsArr);
        var params = {};
        //解析paramsArr配置
        if (paramsArr) {
            paramsArr.forEach((item, index) => {
                params[item[0]] = item[1];
            });
        }
        //拼接参数串
        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/data/dataCollection/log.gif?args=' + encodeURIComponent(args);
        img.src = src;
    }

})(window);

如上代码所示,是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属性指向后端脚本并携带参数,就轻松实现了跨域请求。

**
注意:ma.js和log.gif静态资源放位置需要让后端解析方知道**

数据收集

cj.trackInfo([['userName', '张三'], ['userPhone', '15900123311'], ['userID', '420444199812120001']]);

后端处理

@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,返回到前端代码中。
下图是在控制台拿到的用户信息:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值