I believe that friends who have used Google Analytics understand its powerful functions.
Due to work needs, I recently downloaded a copy of the urchin.js code and studied it. Because there are few comments and the naming is difficult to understand. I studied for a month and achieved some success. I rewrote the code. And added comments to share with everyone. Google's user identification code is deleted here. /**//*
=====================================
|--------Author By BlackSoul---------|
|----------------2006.04.27--------------|
|[email protected] ------|
|----------------QQ:9136194--------------|
|------http://blacksoul.cnblogs.cn---|
======================================
*/
//Define global variables
var ur = ""; //Source address
var urp = new Array(); //Source parameter name
var urpv = new Array(); //Source parameter value
var arrayCount = 0; //Number of parameters
pageOpen = new Date(); //Time to enter the page
var reqURL = " http://192.168.0.219/Analytics/ "; //Page address to receive data
var GUID = Math.round(Math.random()*2147483647); //User’s unique random number
var title = document.title; //Web page title
var uexp = pageOpen.getTime() + (1000 * 60 * 60 * 24 * 30); //Set the cookie expiration time and limit the return users
var rtu = "false"; //Indicate whether the user returns to visit the user
//Browser feature information
var brower = new Array();
/**//*
* browser[0] browser type
* browser[1] browser version
* brower[2] Whether the browser java is turned on 1 on - 1 off
* browser[3] browser flash version
* browser[4] browser operating system
* browser[5] browser resolution
* browser[6] browser color depth
* browser[7] browser language
* brower[8] browser plug-in
*/
var sEn=new Array(); //The name of the search engine
var keyWord=new Array(); //Keyword transmission form
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";
Some global quantities are defined here, where upr and urpv are source parameters and references. For example, the source is http://www.google.com/?p=BlackSoul&q=javascript , then urp[0]="p",urp[ 1]="q" corresponds to urpv[0]="BlackSoul",urpv[1]="javascript".
But in the final transmission, it is passed to the server in the form of delimiters.
GUID is a random number, which is how Google does it. I didn't figure out why it needed to save a random number at first, but I later figured it out after analyzing the data. In order to verify the uniqueness of the user.
The following is the function processing:
//--------------------------------Compare urls, if it is a search engine, save the keyword-------- -----
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 "";
}
//Convert URL to address and page parameters and parameter value parameter uri to page address
function gethn(uri)
{
if(!uri || uri == "") return "";
ur = uri;
varsub;
//with parameters
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;
}
//----------------------------------Obtain domain name----------------- ----------------------------
function getHostName(url)
{
url = url.substring(url.indexOf('://')+3,url.length);
url = url.substring(0,url.indexOf("/"));
return url;
}
//---------------------------------Get the flash version----------------- --------------------------
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);
}
//--------------------------Set asynchronous transmission------------------ ------------------
function createXMLHttpRequest()
{
if (window.XMLHttpRequest)
{
return new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
return new ActiveXObject("Microsoft.XMLHttp");
}
} The above method can obtain some basic information. But the key issue is to set user cookies, determine return visits, determine the last visit time, and set its GUID. After looking here for a long time, I didn’t find out how Google does it... So I thought I came up with some stupid methods. See the code:
//Browser feature information
functionBrowserInfo()
{
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;
}
//Resolution
brower[5] = sr;
//Color depth
brower[6] = sc;
//Plug-in list
brower[8] = getPlugin();
}
//-----------------------Get the current address--------------------- --------
function getHref()
{
return document.location.href;
}
//-----------------------cookie operation starts--------------------- -------------------------------------------------- ---------------------------------------------
function setCookie(name, value)
//Set cookie value
{
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)
{
//Set expiration time 24 hours
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)
//Delete Cookie
{
var exp = new Date();
exp.setTime (exp.getTime() - 1);
var cval = getCookie (name);
document.cookie = name + "=" + cval + "; expires="+ exp.toGMTString();
}
//Get the value of 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;
}
}
//-----Get whether the cookie of GUID exists---------------------------------- ----------------
function getCookieValue()
{
var guid = getCookie("GUID");
if(guid != null)
{
return guid;
}
else
{
return "noCookie";
}
}
//---------------------Get registered user cookie---------------------- -----------------------
function getRegUserCookie()
{
return ;
}
//-----------------------------Cookie operation completed---------------- -------------------------------------------------- ------------------------------------------
//------ ---------------------Get the operating system-------------------------- -
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];
}
//Get the plug-in
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);
}
One thing that needs to be explained is the GetResidentTime function. Google uses the img.load method to load the page of receiving and processing information. You need to configure the server side to compile and run files with the suffix .gif or other forms you choose using aspx. .Because I originally considered using xmlHttp asynchronous call. But sometimes it is not executed when the page exits. So it is abandoned. The code is as follows: 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));
//---------------------Modify here to receive link address XML asynchronous transmission-------------- -----------------------
// var xmlHttp = createXMLHttpRequest();
// xmlHttp.open("POSt", reqURL + firstvisit.aspx?" + StrPara(), false);
// xmlHttp.send(null);
//-------------------------------Transmission in picture form----------------- -----------------------------------------------
if(isReturn() == false)
{
var i = new Image(1,1);
i.src = reqURL + "firstVisit.aspx?" + StrPara() + "&GUID=" + GUID;
i.onload = function() {LoadVoid();}
//Information entering the page
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();}
}
} Finally it was called. I used window.onunload = GetResidentTime
You can print out the parameters passed and take a look. You should be able to understand their meaning.
The rest is the server-side processing. The server-side processing is actually quite simple. Get the value of the request, verify it and save it into the database. Now that we have the data, the analysis can be handled by the user according to his own requirements.. Add one sentence , the IP address is obtained and saved by the server.
When using it, remember to put it on the server side, and then use <javascript language="javascript" type="text/javascript" src=server address+path+"statistics.js"> </script> Attach the complete code http://blacksoul.cnblogs.com/archive/2006/05/19/404563.html