JavaScript implements user behavior tracking collection

The act of collecting user privacy is no longer a new topic (collecting is no longer a peek), and even G and MS show off repeatedly. Of course, due to reasons, enterprises can not understand users'behavior through various means, which can be used as a basis for decision support; usually manifested as cross-disciplinary collection(Browser, Intelligence System, OS Etc.)), business, product data collection, of course, collection methods are also different.The following shows how client-side scripting can be used to collect Web site user behavior data to judge page loading, execution time, user retention time, page submission rate, success rate, page errors, etc. (This example is simple to implement and can be reconstructed appropriately for specific complex business data collection)And transformation).

1. Collect basic data

Base Data Coverage

(1) Business Class: Business Flow Page Address, User Stay Time, Open Number,

Session ID, Client IP, Business Flow Steps, etc.

(2) Auxiliary classes: browser, OS, COOKIE, etc.

(3) Example

  1. /* 
  2.     Record Construction Base Data 
  3. */  
  4. var Logger = {  
  5.     Debug: false,  
  6.     UserControl: 'inputUser',  
  7.     HistoryControl: 'inputHistory',  
  8.     TimerControl: 'inputTimer',  
  9.     GetUser: function() {  
  10.         if (!$f(this.UserControl)) return ",,";  
  11.         return $f(this.UserControl).value;  
  12.     },  
  13.     /*-- attribute --*/  
  14.     Guid: function() {  
  15.         return this.GetUser().split(',')[0];  
  16.     },  
  17.     SessionID: function() {  
  18.         return this.GetUser().split(',')[1];  
  19.     },  
  20.     GetStep: function() {  
  21.         return this.GetUser().split(',')[2];  
  22.     },  
  23.     ProcessTime: function() {  
  24.         if (!$f(this.TimerControl)) return "0";  
  25.         return $f(this.TimerControl).value;  
  26.     },  
  27.     AppSys: 1, //Different System Numbers  
  28.     Environment: ''//Environment.Dev: Develop Dev, Test, Official  
  29.     IsNewSite: 1,  
  30.     //Whether history returns  
  31.     IsHistory: function() {  
  32.         if (!$f(this.HistoryControl)) return false;  
  33.         if ($f(this.HistoryControl).value.length > 0)  
  34.             return true;  
  35.         //if (this.IsSuccReturn()) return true; //Successful return non-historic  
  36.         return false;  
  37.     },  
  38.     IsStep2History: function() { //Whether to return to history for step 2  
  39.         if (!$f(this.HistoryControl)) return false;  
  40.         var history = $f(this.HistoryControl).value;  
  41.         if (history.length == 0)  
  42.             return false;  
  43.         if (history.split(',').length > 1)  
  44.             return true;  
  45.         return false;  
  46.     },  
  47.     //Whether to return for page reload  
  48.     IsReturn: function() {  
  49.         if (typeof getUrlParam != "function"return false;  
  50.         var para = getUrlParam("return");  
  51.         if (para == "1"return true;  
  52.         return false;  
  53.     },  
  54.     //Successfully returned  
  55.     IsSuccReturn: function() {  
  56.         var para = getUrlParam("succret");  
  57.         if (para == "1"return true;  
  58.         return false;  
  59.     },  
  60.     //tracetype,guid,sessionid,processtime,description  
  61.     WriteStepLog: function() {  
  62.         var argc = arguments.length;  
  63.         var traceType = (argc > 0) ? arguments[0] : "";  
  64.         var guid = (argc > 1) ? arguments[1] : "";  
  65.         var sessionID = (argc > 2) ? arguments[2] : "";  
  66.         var processTime = (argc > 3) ? (arguments[3] == "" ? "0" : arguments[3]) : "0";  
  67.         var description = (argc > 4) ? arguments[4] : "";  
  68.         var url = (argc > 5) ? arguments[5] : "";  
  69.         /*with (Trace.Parameter) 
  70.         { 
  71.         TraceType = traceType; 
  72.         Guid = guid; 
  73.         SessionID = sessionID; 
  74.         PageUrl = window.location.href; 
  75.         ProcessTime = processTime; 
  76.         //set const value 
  77.         AppSys = 1; 
  78.         Environment = Environment.Dev; //Offical 
  79.         IsNewSite = 1; 
  80.         Description = description; 
  81.         }*/  
  82.         Trace.Parameter.TraceType = traceType;  
  83.         Trace.Parameter.Guid = guid;  
  84.         Trace.Parameter.SessionID = sessionID;  
  85.         if (url.length == 0) {  
  86.             url = window.location.href;  
  87.             //alert("self:" + window.location.href + ",refer:" + self.document.referrer);  
  88.             if (url.toLowerCase().indexOf('errorpage.aspx') > -1 && traceType.indexOf('ret') == -1) {  
  89.                 if (document.referrer != null && document.referrer != "") url = document.referrer;  
  90.             }  
  91.         }  
  92.         Trace.Parameter.PageUrl = url;  
  93.         Trace.Parameter.ProcessTime = processTime;  
  94.         Trace.Parameter.AppSys = this.AppSys;  
  95.         if (this.Environment.length == 0) this.Environment = Environment.Official;  
  96.         var curUrl = window.location.href.toLowerCase();  
  97.         if (curUrl.indexOf('https://') > -1) {  
  98.             this.Environment = this.Environment.replace('http://''https://');  
  99.         }  
  100.         Trace.Parameter.Environment = this.Environment;  
  101.         Trace.Parameter.IsNewSite = this.IsNewSite;  
  102.         Trace.Parameter.Description = escape(description);  
  103.         if (this.Debug) {  
  104.             alert(Trace.Parameter.TraceType + "," + Trace.Parameter.Guid + "," + Trace.Parameter.SessionID + ","  
  105.             + Trace.Parameter.ProcessTime + "," + Trace.Parameter.Description);  
  106.         }  
  107.         Trace.Submit(Trace.Parameter, null'img');  
  108.     },  
  109.     WriteOpenLog: function() {  
  110.         try {  
  111.             var argc = arguments.length;  
  112.             var step = (argc > 0) ? arguments[0] : "";  
  113.             var desc = (argc > 1) ? arguments[1] : "";  
  114.             if (typeof PTID != "undefined" && PTID.length > 0) {  
  115.                 desc += ",PTID:" + PTID;  
  116.             }  
  117.             var loginstep = this.GetStep();  
  118.             /*if (this.IsSuccReturn()) { //Successful Return 
  119.             Logger.WriteStepLog(Step.succret, this.Guid(), this.SessionID(), this.ProcessTime(), desc); 
  120.             this.SetTimer(); 
  121.             }*/  
  122.             if (step == "step1" && !this.IsHistory() && typeof loginstep != "undefined" && loginstep.length > 0) { //Logon Return (the first step occurs)  
  123.                 Logger.WriteStepLog(loginstep, this.Guid(), this.SessionID(), this.ProcessTime(), desc);  
  124.             }  
  125.             else if (step == "step1" && !this.IsHistory() && !this.IsReturn()) //not history back,not page reload  
  126.             {  
  127.                 Logger.WriteStepLog(step, this.Guid(), this.SessionID(), this.ProcessTime(), desc);  
  128.             }  
  129.             else if ((step == "step2" && !this.IsStep2History()) || step == "step3") { //Step 2, Step 3  
  130.                 Logger.WriteStepLog(step, this.Guid(), this.SessionID(), this.ProcessTime(), desc);  
  131.                 this.SetTimer();  
  132.             }  
  133.             else if (step == "password" || step == "mobile" || step == "cancelbind") { //No attributes such as historical returns at all  
  134.                 Logger.WriteStepLog(step, this.Guid(), this.SessionID(), this.ProcessTime(), desc);  
  135.                 this.SetTimer();  
  136.             }  
  137.             else if (this.IsHistory() || this.IsStep2History() || this.IsReturn()) { //History Return  
  138.                 Logger.WriteStepLog(step + "ret"this.Guid(), this.SessionID(), "0", desc);  
  139.                 this.SetTimer();  
  140.             }  
  141.             else {  
  142.                 Logger.WriteStepLog(step, this.Guid(), this.SessionID(), "0", desc);  
  143.             }  
  144.         }  
  145.         catch (e) {  
  146.   
  147.         }  
  148.     },  
  149.     WriteSubmitLog: function() {  
  150.         try {  
  151.             var argc = arguments.length;  
  152.             var step = (argc > 0) ? arguments[0] : "";  
  153.             var desc = (argc > 1) ? arguments[1] : "";  
  154.             var url = (argc > 2) ? arguments[2] : "";  
  155.             if (typeof PTID != "undefined" && PTID.length > 0) {  
  156.                 desc += ",PTID:" + PTID;  
  157.             }  
  158.             Logger.WriteStepLog(step, this.Guid(), this.SessionID(), this.ProcessTime(), desc, url);  
  159.             $f(this.HistoryControl).value = "1";  
  160.             //set step2  
  161.             if (step == "step2submit") {  
  162.                 $f(this.HistoryControl).value = "1,1";  
  163.             }  
  164.             this.SetTimer();  
  165.         }  
  166.         catch (e) {  
  167.         }  
  168.     },  
  169.     SetTimer: function() { //reset timer  
  170.         if (Timer && typeof Timer != "undefined") {  
  171.             Timer.Reset();  
  172.         }  
  173.     },  
  174.     DirectOpenLog: function() {  
  175.         try {  
  176.             var argc = arguments.length;  
  177.             var step = (argc > 0) ? arguments[0] : "";  
  178.             var desc = (argc > 1) ? arguments[1] : "";  
  179.             if (typeof PTID != "undefined" && PTID.length > 0) {  
  180.                 desc += ",PTID:" + PTID;  
  181.             }  
  182.             this.AppSys = 2;  
  183.             Logger.WriteStepLog(step, this.Guid(), this.SessionID(), this.ProcessTime(), desc);  
  184.             if (step != Step.step1) {  
  185.                 this.SetTimer();  
  186.             }  
  187.         }  
  188.         catch (e) {  
  189.         }  
  190.     }  
  191. };  
  192. var $f = function(name) {  
  193.     return document.getElementById(name);  
  194. }  
  195. //Log client script errors  
  196. window.onerror = function GetErrors(error) {  
  197.     try {  
  198.         var msg;  
  199.         for (var i = 0; i < arguments.length; i++) {  
  200.             if (i == 0 || i == 2) {  
  201.                 msg += " | " + arguments[i];  
  202.             }  
  203.         }  
  204.         if (msg.length > 0 && typeof Logger != 'undefined') {  
  205.             Logger.WriteStepLog('syserror''-''-''', msg);  
  206.         }  
  207.         window.onerror = null;  
  208.         return true;  
  209.     } catch (e) { };  
  210. }  

2. Time Statistics

Calculate the user's stay time in the current view by placing a timer on the page.

Example:

  1. /*--------Timer Script------------- 
  2.  
  3. * Page Timer Control 
  4. * 1,Timer.BindControl = 'inputTimer'; 
  5. * 2,<input id="inputTimer" type="hidden" class="timer" /> 
  6. * Use EndTime - StratTime when cookies are not written and timers are not displayed 
  7. */  
  8. var up, down;  
  9. var cmin1, csec1, clock;  
  10. var Timer = {  
  11.     Debug: false,  
  12.     BindControl: 'inputTimer',  
  13.     StartTime: '',  
  14.     EndTime: '',  
  15.     StartTimer: function() {  
  16.         if (!$f(this.BindControl)) return;  
  17.         if ($f(this.BindControl).value != ""return;  
  18.         //$("#" + this.BindControl).val("");  
  19.         cmin1 = 0;  
  20.         csec1 = 0;  
  21.         //Record each page separately, do not use cookies, block  
  22.         //        var cookie = GetCookie("Timer");  
  23.         //        if (cookie) {  
  24.         //            cmin1 = parseInt(this.Minutes(cookie));  
  25.         //            csec1 = parseInt(this.Seconds(cookie));  
  26.         //            DeleteCookie("Timer");  
  27.         //        }  
  28.         //        else {  
  29.         //            cmin1 = csec1 = 0;  
  30.         //        }  
  31.         this.Repeat();  
  32.     },  
  33.     SetValue: function() {  
  34.         var html = $f(this.BindControl).value;  
  35.         if (html != null && html.length > 0) SetCookie("Timer", html);  
  36.     },  
  37.     Minutes: function(data) {  
  38.         for (var i = 0; i < data.length; i++) if (data.substring(i, i + 1) == ":"break;  
  39.         return (data.substring(0, i));  
  40.     },  
  41.     Seconds: function(data) {  
  42.         for (var i = 0; i < data.length; i++) if (data.substring(i, i + 1) == ":"break;  
  43.         return (data.substring(i + 1, data.length));  
  44.     },  
  45.     Display: function(min, sec) {  
  46.         var disp = "";  
  47.         if (min <= 9) disp += "0" + min + ":";  
  48.         else disp += min + ":";  
  49.         if (sec <= 9) disp += "0" + sec;  
  50.         else disp += sec;  
  51.         return (disp);  
  52.     },  
  53.     Repeat: function() {  
  54.         csec1++;  
  55.         if (csec1 == 60) { csec1 = 0; cmin1++; }  
  56.         $f(this.BindControl).value = this.Display(cmin1, csec1);  
  57.         if (this.Debug) $f("inputDebug").value = this.Display(cmin1, csec1);  
  58.         clock = window.setTimeout(function() { Timer.Repeat() }, 1000);  
  59.     },  
  60.     //Restart Timing  
  61.     Reset: function() {  
  62.         $f(this.BindControl).value = "";  
  63.         window.clearTimeout(clock);  
  64.         Timer.StartTimer();  
  65.     },  
  66.     AddTrigger: function() {  
  67.         var list = document.getElementsByTagName("INPUT");  
  68.         for (var i = 0; i < list.length; i++) {  
  69.             if (list[i].type.toUpperCase() == 'TEXT') {  
  70.                 if (list[i].addEventListener) {  
  71.                     list[i].addEventListener("keyup"function() { Timer.StartTimer(); }, false);  
  72.                 }  
  73.                 else {  
  74.                     list[i].attachEvent("onkeyup"function() { Timer.StartTimer(); });  
  75.                 }  
  76.             }  
  77.         }  
  78.     }  
  79. };  
  80. if (document.all) {  
  81.     window.attachEvent("onload"function() { Timer.AddTrigger() });  
  82. }  
  83. else {  
  84.     window.addEventListener("load"function() { Timer.AddTrigger() }, false);  
  85. }  
  86. if (Timer.Debug) {  
  87.     if (!document.getElementById("inputDebug")) {  
  88.         document.write("<input type='text' id='inputDebug' />");  
  89.     }  
  90. }  
  91. /* Compatible with two mode settings Cookie*/  
  92. //$(window).unload(function() { Timer.SetValue(); });  
  93. //$("form").submit(function() { Timer.SetValue(); });  

3. Asynchronous Recording

Send collected data to target server asynchronously via GET, POST

Example:

  1. /*--------Trace Script-------------*/  
  2. var Step =  
  3. {  
  4.     /* step */  
  5.     step1: "step1"//The first step opens, no history returns, successful returns  
  6.     step2: "step2",  
  7.     step3: "step3",  
  8.     /* post */  
  9.     step1submit: "step1submit"//Step 1 Submit  
  10.     step2submit: "step2submit",  
  11.     step3submit: "step3submit",  
  12.     step3resubmit: "step3resubmit"//Step 3 Resubmit  
  13.     /* success */  
  14.     success:"success"//Operation Successful  
  15.     succret: "succret"//Successful Return  
  16.     step1ret: "step1ret"//Return to Step One  
  17.     step2ret: "step2ret",  
  18.     step3ret: "step3ret",  
  19.     /* error */  
  20.     error:"error"//operation failed  
  21.     errstep1: "errstep1"//Step 1 Error Page Record  
  22.     errstep2: "errstep2",  
  23.     errstep3: "errstep3",  
  24.     errstep1ret: "errstep1ret"//Error Page Back to First Step  
  25.     errstep2ret: "errstep2ret",  
  26.     errstep3ret: "errstep3ret",  
  27.     /* login */  
  28.     loginb1: "loginb1"//Bank card login return  
  29.     loginc1: "loginc1"//Physical Card Login Return  
  30.     loginbind: "loginbind"//Log in at one point and return  
  31.     step1login: "step1login"//First step login interface  
  32.     /* other */  
  33.     bind: "bind"//User Binding  
  34.     mobile: "mobile"//Modify mobile number  
  35.     password: "password"//Change Password  
  36.     cancelbind: "cancelbind"//Cancel Service  
  37.     Login: "Login"//User Log  
  38.     querydeposit: "querydeposit"//Recharge record  
  39.     querycardbalance: "querycardbalance"//Physical card balance  
  40.     clickkf: "clickkf"//Click on Online Customer Service  
  41.     closekf: "closekf"//Turn off Online Customer Service  
  42.     clickaccount1: "clickaccount1"//Click to add a new common account  
  43.     clickaccount2: "clickaccount2" //Click the Add OK button  
  44. };  
  45. var Environment = { Dev: "http://dev.xxx.com", Test: "http://test.xxx.com", Official: "http://www.xxx.com" }  
  46. var Trace = {  
  47.     AutoSubmit: false//Whether to process the form automatically when it is submitted  
  48.     Parameter: {  
  49.         TraceType: ''//TraceType.open  
  50.         Guid: '0',  
  51.         SessionID: '',  
  52.         PageUrl: '',  
  53.         Description: '',  
  54.         ProcessTime: '',  
  55.         IsNewSite: false,  
  56.         AppSys: 1,  
  57.         ClientIP: '',  
  58.         Environment: Environment.Official,  
  59.         Extend: {}  
  60.     },  
  61.     MyAjax: function() {  
  62.         this.xml = false;  
  63.         this.GetXmlHttp = function() {  
  64.             if (!this.xml && typeof XMLHttpRequest != 'undefined') {  
  65.                 this.xml = new XMLHttpRequest();  
  66.             }  
  67.             else {  
  68.                 var MSXML = ['MSXML2.XMLHTTP.5.0''MSXML2.XMLHTTP.4.0''MSXML2.XMLHTTP.3.0''MSXML2.XMLHTTP''Microsoft.XMLHTTP'];  
  69.                 for (var i = 0; i < MSXML.length; i++) {  
  70.                     try {  
  71.                         this.xml = new ActiveXObject(MSXML[i]);  
  72.                         break;  
  73.                     }  
  74.                     catch (e) {//alert(e.message);  
  75.                     }  
  76.                 }  
  77.             }  
  78.         }  
  79.         this.GetXmlHttp();  
  80.         var xmlHttp = this.xml;  
  81.         var ajax = this;  
  82.         var callBack = null;  
  83.         this.updatePage = function() {  
  84.             if (xmlHttp.readyState == 4) {  
  85.                 var response = xmlHttp.responseText;  
  86.                 if (callBack != null && typeof callBack == "function") {  
  87.                     callBack(response);  
  88.                 }  
  89.             }  
  90.         }  
  91.         this.toQueryString = function(json) {  
  92.             var query = "";  
  93.             if (json != null) {  
  94.                 for (var param in json) {  
  95.                     query += param + "=" + escape(json[param]) + "&"  
  96.                 }  
  97.             }  
  98.             return query;  
  99.         }  
  100.         //Submit parameters, callback functions, post, get methods  
  101.         this.invoke = function(params, pageCallBack, method) {  
  102.             if (xmlHttp) {  
  103.                 var query = "";  
  104.                 query += this.toQueryString(params);  
  105.                 query = query.substring(0, query.length - 1);  
  106.                 //var thisReg = new RegExp(/'|"/gi);  
  107.                 //query = query.replace(thisReg, "");  
  108.                 callBack = pageCallBack;  
  109.                 if (method != null && method.toUpperCase() == "GET") {  
  110.                     var url = params.Environment + "/Trace.aspx?" + query;  
  111.                     xmlHttp.onreadystatechange = ajax.updatePage;  
  112.                     xmlHttp.open("GET", url, true);  
  113.                     xmlHttp.setRequestHeader("TraceAjax-Ver""ver1.0");  
  114.                     xmlHttp.send(null);  
  115.                 }  
  116.                 else if (method != null && method.toUpperCase() == "POST") {  
  117.                     var url = params.Environment + "/Trace.aspx";  
  118.                     //  xmlHttp.setRequestHeader("Content-Length",query);   
  119.                     xmlHttp.onreadystatechange = ajax.updatePage; //new CallClient(this);  
  120.                     xmlHttp.open("POST", url, true);  
  121.                     xmlHttp.setRequestHeader("Content-type""application/x-www-form-urlencoded");  
  122.                     xmlHttp.setRequestHeader("TraceAjax-Ver""ver1.0");  
  123.                     xmlHttp.send(query);  
  124.                 }  
  125.                 else { //Cross-domain  
  126.                     Trace.CreateTraceImg();  
  127.                     document.getElementById("traceImg").src = params.Environment + "/Trace.aspx?a=" + Math.random(1000000000) + "&" + query;  
  128.                 }  
  129.             }  
  130.         }  
  131.     },  
  132.     CreateTraceImg: function() {  
  133.         if (!document.getElementById("traceImg")) {  
  134.             document.write("<img id=\"traceImg\" style='display:none' />");  
  135.             //            var imgNode = document.createElement("img")  
  136.             //            imgNode.setAttribute("id", "traceImg")  
  137.             //            imgNode.style.display = "none";  
  138.             //            document.body.appendChild(imgNode);  
  139.         }  
  140.     },  
  141.     Submit: function(params, pageCallBack, method) {  
  142.         try {  
  143.             var ajax = new Trace.MyAjax();  
  144.             //Verify that step is correct  
  145.             //        for (var i = 0; i < Step.length; i++) {  
  146.             //            if (params.TraceType == Step[i]) {  
  147.             //                alert(Step[i]);  
  148.             //            }  
  149.             //        }  
  150.             ajax.invoke(params, pageCallBack, method);  
  151.         }  
  152.         catch (e) {  
  153.         }  
  154.     }  
  155. };  
  156. Trace.CreateTraceImg();  

4. Backend data analysis

Combined with the user data collected in the foreground, the background can be initially completed. The number of times each page is opened, the length of time taken, the submission rate, and the success rate of the background business flow, etc. show the data analysis interface through the report form, so that you can monitor user behavior anomalies, monitor system fluctuations and impact areas.

5. Extension

By recording the source address, you can analyze the process of user behavior in more detail.

Calculate the click-through rate by appending the click-through of page elements.

Although the server side can also do these processes, it is too cumbersome to insert many log records in different processes and POST to the server side.

In addition, the tracking server verifies the validity and authorization of data requests from the source.

*Note: When using system methods such as binding event window.onload during the Tracer process, you need to be careful not to override the method to avoid page conflicts with the application. You can add event monitoring by eg:

  1. AddTrigger: function() {  
  2.     var list = document.getElementsByTagName("INPUT");  
  3.     for (var i = 0; i < list.length; i++) {  
  4.         if (list[i].type.toUpperCase() == 'TEXT') {  
  5.             if (list[i].addEventListener) {  
  6.                 list[i].addEventListener("keyup"function() { Timer.StartTimer(); }, false);  
  7.             }  
  8.             else {  
  9.                 list[i].attachEvent("onkeyup"function() { Timer.StartTimer(); });  
  10.             }  
  11.         }  
  12.     }  
  13. }  

6. About script compression

JSA compression tool is recommended for reasons of stability, reliability and guaranteed compression quality

But you need to install it Java RUNTIME


Keywords: xml Mobile JSON Session

Added by pbeerman on Wed, 03 Jul 2019 20:28:38 +0300