相信用過(guò)google的analytics的朋友都了解其功能的強(qiáng)大.
由于工作需要,最近將其urchin.js的代碼down了一份下來(lái)研究了一下.由于其注釋很少,命名也很難讀懂.研究了1個(gè)月.小有所成.將其代碼重寫并加上了注釋.與大家一同分享.這里面將google的用戶識(shí)別代碼刪除. /**//*
=====================================
|--------Author By BlackSoul---------|
|------------2006.04.27--------------|
|--------BlackSoulylk@Gmail.com------|
|------------QQ:9136194--------------|
|------http://blacksoul.VEVb.cn---|
======================================
*/
//定義全局量
var ur = ""; //來(lái)源地址
var urp = new Array(); //來(lái)源參數(shù)名稱
var urpv = new Array(); //來(lái)源參數(shù)值
var arrayCount = 0; //參數(shù)數(shù)目
pageOpen = new Date(); //進(jìn)入頁(yè)面的時(shí)間
var reqURL = "var GUID = Math.round(Math.random()*2147483647); //用戶唯一隨機(jī)數(shù)
var title = document.title; //網(wǎng)頁(yè)標(biāo)題
var uexp = pageOpen.getTime() + ( 1000 * 60 * 60 * 24 * 30 ); //設(shè)置cookie過(guò)期時(shí)間 既回訪用戶的限定
var rtu = "false"; //指示用戶是否回訪用戶
//瀏覽器特征信息
var brower = new Array();
/**//*
* brower[0] 瀏覽器類型
* brower[1] 瀏覽器版本
* brower[2] 瀏覽器java是否打開 1開-1關(guān)
* brower[3] 瀏覽器Flash版本
* brower[4] 瀏覽器操作系統(tǒng)
* brower[5] 瀏覽器分辨率
* brower[6] 瀏覽器色深
* brower[7] 瀏覽器語(yǔ)言
* brower[8] 瀏覽器插件
*/
var sEn=new Array(); //搜索引擎的名稱
var keyWord=new Array(); //關(guān)鍵字傳輸形式
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為來(lái)源參數(shù)和指,比如來(lái)源為http://www.google.com/?p=BlackSoul&q=javascrJavascript".
但是最終傳輸?shù)臅r(shí)候是以分隔符的形式傳遞給服務(wù)器端的.
GUID為隨機(jī)數(shù),google是這么做的.當(dāng)初沒有想通為什么要保存一個(gè)隨機(jī)數(shù),后來(lái)分析數(shù)據(jù)的才明白過(guò)來(lái).為了驗(yàn)證用戶的唯一性.
以下是函數(shù)處理:
//-----------------------------比較url,如果為搜索引擎則保存關(guān)鍵字-------------
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轉(zhuǎn)換為地址和頁(yè)面參數(shù)和參數(shù)值 參數(shù)uri為頁(yè)面地址
function gethn(uri)
{
if(!uri || uri == "") return "";
ur = uri;
var sub;
//帶參數(shù)
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);
}
//--------------------------設(shè)置異步傳輸-----------------------------------
function createxmlHttpRequest()
{
if (window.xmlhttpRequest)
{
return new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
return new ActiveXObject("Microsoft.XMLHttp");
}
} 以上的方法可以取得一些基本信息.但是關(guān)鍵的問題還是設(shè)置用戶cookie,判斷回訪,判斷最后一次訪問時(shí)間,并設(shè)置其GUID.這里看了很久沒有發(fā)現(xiàn)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();
}
//-----------------------獲得當(dāng)前地址-----------------------------
function getHref()
{
return document.location.href;
}
//-----------------------cookie操作開始-----------------------------------------------------------------------------------------------------------------
function setCookie(name, value)
//設(shè)定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)
{
//設(shè)置過(guò)期時(shí)間24小時(shí)
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";
}
}
//---------------------獲得注冊(cè)用戶cookie---------------------------------------------
function getRegUserCookie()
{
return ;
}
//-----------------------------cookie 操作完畢------------------------------------------------------------------------------------------------------------
//---------------------------得操作系統(tǒng)---------------------------
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);
}
需要說(shuō)明的一點(diǎn)是GetResidentTime這個(gè)函數(shù),google采用了img.load的方法加載了接收處理信息頁(yè)面的,需要再服務(wù)器端配置將后綴為.gif或你所取的其他形式的文件使用aspx的方式編譯運(yùn)行.因?yàn)槲以瓉?lái)考慮的是使用xmlHttp異步調(diào)用.但是頁(yè)面退出的時(shí)候有時(shí)候不執(zhí)行.所以就棄用了.代碼如下: 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();}
//進(jìn)入頁(yè)面的信息
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();}
}
} 最后就是調(diào)用了.我使用了window.onunload = GetResidentTime
傳遞的參數(shù)大家可以打印出來(lái)看一下.應(yīng)該可以明白其意思.
剩下的就是服務(wù)器端的處理了,在服務(wù)器端處理其實(shí)相當(dāng)簡(jiǎn)單.取得request的值,驗(yàn)證并保存入數(shù)據(jù)庫(kù).現(xiàn)在有了數(shù)據(jù),分析的事情就由用戶按照自己的要求來(lái)處理了..補(bǔ)充一句,ip地址是由服務(wù)器端來(lái)取得保存的.
使用的時(shí)候記得一定將其放到服務(wù)器端,然后使用<javascript language="javascript" type="text/javascript" src=服務(wù)器地址+路徑+"statistics.js"> </script> 附上完整的代碼http://m.survivalescaperooms.com/Files/BlackSoul/statistic.rar下載.
該例子我在IE,Firefox,netscape下面測(cè)試都很正常.搞了一個(gè)月,總算有所成就了.但是還有很多需要改進(jìn)的地方,希望做過(guò)的,感興趣的朋友多多指點(diǎn)交流.
http://blacksoul.VEVb.com/archive/2006/05/19/404563.html
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注