zoukankan      html  css  js  c++  java
  • [转]google的分析(analytics)js代码分析以及重写

    相信用过google的analytics的朋友都了解其功能的强大.
    由于工作需要,最近将其urchin.js的代码down了一份下来研究了一下.由于其注释很少,命名也很难读懂.研究了1个月.小有所成.将其代码重写并加上了注释.与大家一同分享.这里面将google的用户识别代码删除. /**//*
    复制内容到剪贴板
    代码:
    =====================================
    |--------Author By BlackSoul---------|
    |------------2006.04.27--------------|
    |--------BlackSoulylk@gmail.com------|
    |------------QQ:9136194--------------|
    |------http://blacksoul.cnblogs.cn---|
    ======================================
    */

    //定义全局量
    var ur = "";                                                  //来源地址
    var urp = new Array();                                     //来源参数名称
    var urpv = new Array();                                     //来源参数值
    var arrayCount = 0;                                        //参数数目
    pageOpen = new Date();                                        //进入页面的时间
    var reqURL = "http://192.168.0.219/Analytics/";             //接收数据的页面地址
    var GUID = Math.round(Math.random()*2147483647);              //用户唯一随机数
    var title = document.title;                                   //网页标题
    var uexp = pageOpen.getTime() + ( 1000 * 60 * 60 * 24 * 30 ); //设置cookie过期时间 既回访用户的限定
    var rtu = "false";                                            //指示用户是否回访用户

    //浏览器特征信息
    var brower = new Array();
    /**//*
    * brower[0] 浏览器类型
    * brower[1] 浏览器版本
    * brower[2] 浏览器java是否打开 1开-1关
    * brower[3] 浏览器flash版本
    * brower[4] 浏览器操作系统
    * brower[5] 浏览器分辨率
    * brower[6] 浏览器色深
    * brower[7] 浏览器语言
    * brower[8] 浏览器插件
    */
    var sEn=new Array(); //搜索引擎的名称
    var keyWord=new Array(); //关键字传输形式
    sEn[0]="google";        keyWord[0]="q";
    sEn[1]="yahoo";          keyWord[1]="p";
    sEn[2]="msn";          keyWord[2]="q";
    sEn[3]="aol";          keyWord[3]="query";
    sEn[4]="lycos";          keyWord[4]="query";
    sEn[5]="ask";          keyWord[5]="q";
    sEn[6]="altavista";        keyWord[6]="q";
    sEn[7]="search";        keyWord[7]="q";
    sEn[8]="netscape";        keyWord[8]="query";
    sEn[9]="earthlink";        keyWord[9]="q";
    sEn[10]="cnn";          keyWord[10]="query";
    sEn[11]="looksmart"; keyWord[11]="key";
    sEn[12]="about";        keyWord[12]="terms";
    sEn[13]="excite";        keyWord[13]="qkw";
    sEn[14]="mamma";        keyWord[14]="query";
    sEn[15]="alltheweb"; keyWord[15]="q";
    sEn[16]="gigablast"; keyWord[16]="q";
    sEn[17]="voila";        keyWord[17]="kw";
    sEn[18]="virgilio";        keyWord[18]="qs";
    sEn[19]="teoma";        keyWord[19]="q";
    sEn[20]="baidu";        keyWord[20]="wd";
    //test data----------------------------//////////////////////////////-----------/-/-/-/-/-/-/-/-/-/-/-
    sEn[21]="localhost"; keyWord[21]="q";
    这里面定义一些全局的量,其中upr,urpv为来源参数和指,比如来源为http://www.google.com/?p=BlackSoul&q=javascript,则urp[0]="p",urp[1]="q" 相对应的urpv[0]="BlackSoul",urpv[1]="javascript".
    但是最终传输的时候是以分隔符的形式传递给服务器端的.
    GUID为随机数,google是这么做的.当初没有想通为什么要保存一个随机数,后来分析数据的才明白过来.为了验证用户的唯一性.
    以下是函数处理:
    复制内容到剪贴板
    代码:
    //-----------------------------比较url,如果为搜索引擎则保存关键字-------------
    function getKeyword(url)
    {
    var hostname;
    if(url.indexOf(".") == -1)
           {hostname = url;}
    else
           {hostname = url.substring(url.indexOf("."),url.lastIndexOf("."));}
    for(var i = 0; i < sEn.length; i++)
    {
           if(hostname == sEn[i])
           {
             for(var j = 0; j < urp.length; j ++)
             {
                if(urp[j] == keyWord[i])
                {
                       return urpv[j];
                }
             }
           }
    }

    return "";
    }
    //将URL转换为地址和页面参数和参数值 参数uri为页面地址
    function gethn(uri)
    {
    if(!uri || uri == "") return "";
    ur = uri;
    var sub;
    //带参数
    if(ur.indexOf("?") != -1)
    {
           var url = ur.substring(0,ur.indexOf("?"));
           var para = ur.substring(ur.indexOf("?")+1,ur.length);
           while(para.length > 0)
           {
             if(para.indexOf("&") == -1)
             {
                urp[arrayCount] = para.substring(0,para.indexOf("="));
                urpv[arrayCount] = para.substring(para.indexOf("=")+1,para.length);
                break;
             }
             sub = para.substring(0,para.indexOf("&"));
             urp[arrayCount] = sub.substring(0,sub.indexOf("="));
             urpv[arrayCount] = sub.substring(sub.indexOf("=")+1,sub.length);
             para = para.substring(para.indexOf("&")+1,para.length);
             arrayCount ++;
           }
           return url;
    }
    else
           return ur;
    }

    //----------------------------获得域名---------------------------------------------
    function getHostName(url)
    {
    url = url.substring(url.indexOf('://')+3,url.length);
    url = url.substring(0,url.indexOf("/"));
    return url;
    }

    //---------------------------获得flash版本------------------------------------------
    function getFlash() {
    var f="-1",n=navigator;
    if (n.plugins && n.plugins.length) {
       for (var ii=0;ii<n.plugins.length;ii++) {
    if (n.plugins[ii].name.indexOf('Shockwave Flash')!=-1) {
    f=n.plugins[ii].description.split('Shockwave Flash ')[1];
    break;
    }
       }
    } else if (window.ActiveXObject) {
       for (var ii=10;ii>=2;ii--) {
    try {
    var fl=eval("new ActiveXObject('ShockwaveFlash.ShockwaveFlash."+ii+"');");
    if (fl) { f=ii + '.0'; break; }
    }
    catch(e) {}
       }
    }
    if(f == "-1")
    return f;
    else
        return f.substring(0,f.indexOf(".")+2);
    }

    //--------------------------设置异步传输-----------------------------------
    function createXMLHttpRequest()
    {
    if (window.XMLHttpRequest)
    {
           return new XMLHttpRequest();
    }
    else if (window.ActiveXObject)
    {
           return new ActiveXObject("Microsoft.XMLHttp");
    }
    }
    以上的方法可以取得一些基本信息.但是关键的问题还是设置用户cookie,判断回访,判断最后一次访问时间,并设置其GUID.这里看了很久没有发现google是怎么做的...于是自己想了一些笨办法.见一下代码:
    复制内容到剪贴板
    代码:
    //浏览器特征信息
    function BrowserInfo()
    {
    brower[0] = navigator.appName;
    brower[7] = navigator.language;
    if(brower[0] == "Netscape")
    {
           var browerInfo = navigator.userAgent;
           brower[1] = browerInfo.substring(browerInfo.lastIndexOf(" ")+1,browerInfo.length);
           brower[0] = brower[1].substring(0,brower[1].lastIndexOf("/"));
           brower[1] = browerInfo.substring(browerInfo.lastIndexOf("/")+1,browerInfo.length);
           brower[7] = navigator.language;
    }
    else if(brower[0] == "Microsoft Internet Explorer")
    {
           brower[1] = navigator.userAgent.split(";")[1];
           brower[7] = navigator.userLanguage;
    }
    brower[2] = navigator.javaEnabled()?1:-1;
    brower[3] = getFlash();
    brower[4] = getOS();

    if (self.screen) {
           sr=screen.width+"x"+screen.height;
           sc=screen.colorDepth+"-bit";
    }
    else if (self.java)
    {
           var j=java.awt.Toolkit.getDefaultToolkit();
           var s=j.getScreenSize();
           sr=s.width+"x"+s.height;
    }
    //分辨率
    brower[5] = sr;
    //色深
    brower[6] = sc;
    //插件列表
    brower[8] = getPlugin();
    }

    //-----------------------获得当前地址-----------------------------
    function getHref()
    {
    return document.location.href;
    }

    //-----------------------cookie操作开始 -----------------------------------------------------------------------------------------------------------------

    function setCookie(name, value)
    //设定Cookie值
    {
    var expdate = new Date();
    var argv = setCookie.arguments;
    var argc = setCookie.arguments.length;
    var expires = 15768000;
    var path = (argc > 3) ? argv[3] : null;
    var domain = (argc > 4) ? argv[4] : null;
    var secure = (argc > 5) ? argv[5] : false;

    if(expires!=null)
    {
    //设置过期时间24小时
           expdate.setTime(uexp);
           document.cookie = name + "=" + escape (value) +((expires == null) ? "" : ("; expires="+ expdate.toGMTString()))
             + ((path == null) ? "" : ("; path=" + path)) +((domain == null) ? "" : ("; domain=" + domain))
             + ((secure == true) ? "; secure=" : "");
    }
    }

    function delCookie(name)
    //删除Cookie
    {
    var exp = new Date();
    exp.setTime (exp.getTime() - 1);
    var cval = getCookie (name);
    document.cookie = name + "=" + cval + "; expires="+ exp.toGMTString();
    }


    //获得Cookie的值
    function getCookie(fname)
    {
    var name,value;
    var cookies = new Object();
    var beginning,middle,end;

    beginning = 0;
    while(beginning < document.cookie.length)
    {
           middle = document.cookie.indexOf("=",beginning);
           end = document.cookie.indexOf(";",beginning);

           if(end == -1)
           {
             end = document.cookie.length;
           }
           if((middle > end) || (middle == -1))
           {
             name = document.cookie.substring(beginning,end);
             value = "";
           }
           else
           {
             name = document.cookie.substring(beginning,middle);
             value = document.cookie.substring(middle+1,end);
           }
           if(name == fname)
           {
             return unescape(value);
           }
           beginning = end + 2;
    }
    }

    //-----获取GUID的cookie是否存在获得---------------------------------------------------
    function getCookieValue()
    {
    var guid = getCookie("GUID");
    if(guid != null)
    {
           return guid;
    }
    else
    {
           return "noCookie";
    }
    }

    //---------------------获得注册用户cookie---------------------------------------------
    function getRegUserCookie()
    {
    return ;
    }
    //-----------------------------cookie 操作完毕 ------------------------------------------------------------------------------------------------------------

    //---------------------------得操作系统---------------------------
    function getOS()
    {
    var OSlist = new Array();
    var OSName = new Array();
    OSlist[0] = " Windows4.0";    OSName[0] = "Windows 95";
    OSlist[1] = " Windows 98";    OSName[1] = "Windows 98";
    OSlist[2] = " Windows NT 5.0"; OSName[2] = "Windows 2000";
    OSlist[3] = " Windows NT 5.1"; OSName[3] = "Windows XP";
    OSlist[4] = " Windows NT 5.2"; OSName[4] = "Windows Server 2003";
    var ua = navigator.userAgent.split(";");
    for(var i = 0; i < OSlist.length; i++)
    {
           if(ua[2] == OSlist[i])
             return OSName[i];
    }
    return ua[2];
    }

    //获得插件
    function getPlugin()
    {
    var plugin = "";
    var ua = navigator.userAgent.split(";");
    if(ua.length < 4)
           return "";
    for(var i = 4; i < ua.length; i++)
    {
           plugin += ua[i] + ",";
    }
    return plugin.substring(0,plugin.length-2);
    }
    需要说明的一点是GetResidentTime这个函数,google采用了img.load的方法加载了接收处理信息页面的,需要再服务器端配置将后 缀为.gif或你所取的其他形式的文件使用aspx的方式编译运行.因为我原来考虑的是使用xmlHttp异步调用.但是页面退出的时候有时候不执行.所 以就弃用了.代码如下:
    复制内容到剪贴板
    代码:
    function GetResidentTime()
    {
    pageClose = new Date();
    minutes = (pageClose.getMinutes() - pageOpen.getMinutes());
    if(minutes < 0)
    {
           minutes = minutes + 60;
    }
    seconds = (pageClose.getSeconds() - pageOpen.getSeconds());
    if(seconds < 0){ seconds += 60;}
    time = (seconds + (minutes * 60));

    //------------------------修改此处为接收链接地址 XML 异步传输------------------------------------
    // var xmlHttp = createXMLHttpRequest();
    // xmlHttp.open("POSt", reqURL + firstvisit.aspx?" + StrPara(), false);
    // xmlHttp.send(null);
    //----------------------------图片形式传递-------------------------------------------------------
    if(isReturn() == false)
    {
           var i = new Image(1,1);

           i.src = reqURL + "firstVisit.aspx?" + StrPara() + "&GUID=" + GUID;
           i.onload = function() {LoadVoid();}

           //进入页面的信息
           if(getCookieValue("GUID") == "noCookie"){return ;}
           i.src = reqURL + "pageView.gif?" + pageView() + "&st=" + time;
           i.onload=function() {LoadVoid();}
    }
    else
    {

           var i=new Image(1,1);
           i.src = reqURL + "pageView.gif?" + pageView() + "&st=" + time;
           i.onload=function() {LoadVoid();}
    }
    }
    最后就是调用了.我使用了window.onunload = GetResidentTime
    传递的参数大家可以打印出来看一下.应该可以明白其意思.
    剩下的就是服务器端的处理了,在服务器端处理其实相当简单.取得request的值,验证并保存入数据库.现在有了数据,分析的事情就由用户按照自己的要求来处理了..补充一句,ip地址是由服务器端来取得保存的.
    使用的时候记得一定将其放到服务器端,然后使用<javascript language="javascript" type="text/javascript" src=服务器地址+路径+"statistics.js"> </script> 附上完整的代码https://files.cnblogs.com/BlackSoul/statistic.rar下载
  • 相关阅读:
    MovieLens
    牛顿法与拟牛顿法学习笔记(一)牛顿法
    Softmax回归
    PCA练习
    PCA主成分分析
    算法——A*——HDOJ:1813
    spring 入门篇
    java——多线程——单例模式的static方法和非static方法是否是线程安全的?
    java——数据库——commons-DbUtils
    java——HashCode和equal方法
  • 原文地址:https://www.cnblogs.com/goooto/p/1497420.html
Copyright © 2011-2022 走看看