标签:des style http io ar os java sp for
收集用户隐私的行径眼下已不再是什么新鲜的话题(与其说是收集,不如说是偷窥),就连G、MS也屡出风头,当然事出有因,企业通过无法八门的各种手段了解用户的行为,进而作为决策支持的依据;通常表现为跨领域的收集(浏览器、智能系统、OS etc.)、业务、产品数据的收集,当然收集的方式也不一而论。以下展示通过客户端脚本方式收集Web站点用户行为数据的实现方式,以此来判断页面加载过程、执行时间、用户停留时间、页面提交率、成功率、页面错误等(本示例实现较为简单,在特定复杂的业务数据收集时,可适当重构与改造)。
1、收集基础数据
基础数据涵盖
(1) 业务类:业务流页面地址、用户停留时间、打开次数、
会话ID、客户端IP、业务流步骤等
(2) 辅助类:浏览器、OS、COOKIE等
(3) 示例
- var Logger = {
- Debug: false,
- UserControl: ‘inputUser‘,
- HistoryControl: ‘inputHistory‘,
- TimerControl: ‘inputTimer‘,
- GetUser: function() {
- if (!$f(this.UserControl)) return ",,";
- return $f(this.UserControl).value;
- },
-
- Guid: function() {
- return this.GetUser().split(‘,‘)[0];
- },
- SessionID: function() {
- return this.GetUser().split(‘,‘)[1];
- },
- GetStep: function() {
- return this.GetUser().split(‘,‘)[2];
- },
- ProcessTime: function() {
- if (!$f(this.TimerControl)) return "0";
- return $f(this.TimerControl).value;
- },
- AppSys: 1,
- Environment: ‘‘,
- IsNewSite: 1,
-
- IsHistory: function() {
- if (!$f(this.HistoryControl)) return false;
- if ($f(this.HistoryControl).value.length > 0)
- return true;
-
- return false;
- },
- IsStep2History: function() {
- if (!$f(this.HistoryControl)) return false;
- var history = $f(this.HistoryControl).value;
- if (history.length == 0)
- return false;
- if (history.split(‘,‘).length > 1)
- return true;
- return false;
- },
-
- IsReturn: function() {
- if (typeof getUrlParam != "function") return false;
- var para = getUrlParam("return");
- if (para == "1") return true;
- return false;
- },
-
- IsSuccReturn: function() {
- var para = getUrlParam("succret");
- if (para == "1") return true;
- return false;
- },
-
- WriteStepLog: function() {
- var argc = arguments.length;
- var traceType = (argc > 0) ? arguments[0] : "";
- var guid = (argc > 1) ? arguments[1] : "";
- var sessionID = (argc > 2) ? arguments[2] : "";
- var processTime = (argc > 3) ? (arguments[3] == "" ? "0" : arguments[3]) : "0";
- var description = (argc > 4) ? arguments[4] : "";
- var url = (argc > 5) ? arguments[5] : "";
-
- Trace.Parameter.TraceType = traceType;
- Trace.Parameter.Guid = guid;
- Trace.Parameter.SessionID = sessionID;
- if (url.length == 0) {
- url = window.location.href;
-
- if (url.toLowerCase().indexOf(‘errorpage.aspx‘) > -1 && traceType.indexOf(‘ret‘) == -1) {
- if (document.referrer != null && document.referrer != "") url = document.referrer;
- }
- }
- Trace.Parameter.PageUrl = url;
- Trace.Parameter.ProcessTime = processTime;
- Trace.Parameter.AppSys = this.AppSys;
- if (this.Environment.length == 0) this.Environment = Environment.Official;
- var curUrl = window.location.href.toLowerCase();
- if (curUrl.indexOf(‘https://‘) > -1) {
- this.Environment = this.Environment.replace(‘http://‘, ‘https://‘);
- }
- Trace.Parameter.Environment = this.Environment;
- Trace.Parameter.IsNewSite = this.IsNewSite;
- Trace.Parameter.Description = escape(description);
- if (this.Debug) {
- alert(Trace.Parameter.TraceType + "," + Trace.Parameter.Guid + "," + Trace.Parameter.SessionID + ","
- + Trace.Parameter.ProcessTime + "," + Trace.Parameter.Description);
- }
- Trace.Submit(Trace.Parameter, null, ‘img‘);
- },
- WriteOpenLog: function() {
- try {
- var argc = arguments.length;
- var step = (argc > 0) ? arguments[0] : "";
- var desc = (argc > 1) ? arguments[1] : "";
- if (typeof PTID != "undefined" && PTID.length > 0) {
- desc += ",PTID:" + PTID;
- }
- var loginstep = this.GetStep();
-
- if (step == "step1" && !this.IsHistory() && typeof loginstep != "undefined" && loginstep.length > 0) {
- Logger.WriteStepLog(loginstep, this.Guid(), this.SessionID(), this.ProcessTime(), desc);
- }
- else if (step == "step1" && !this.IsHistory() && !this.IsReturn())
- {
- Logger.WriteStepLog(step, this.Guid(), this.SessionID(), this.ProcessTime(), desc);
- }
- else if ((step == "step2" && !this.IsStep2History()) || step == "step3") {
- Logger.WriteStepLog(step, this.Guid(), this.SessionID(), this.ProcessTime(), desc);
- this.SetTimer();
- }
- else if (step == "password" || step == "mobile" || step == "cancelbind") {
- Logger.WriteStepLog(step, this.Guid(), this.SessionID(), this.ProcessTime(), desc);
- this.SetTimer();
- }
- else if (this.IsHistory() || this.IsStep2History() || this.IsReturn()) {
- Logger.WriteStepLog(step + "ret", this.Guid(), this.SessionID(), "0", desc);
- this.SetTimer();
- }
- else {
- Logger.WriteStepLog(step, this.Guid(), this.SessionID(), "0", desc);
- }
- }
- catch (e) {
-
- }
- },
- WriteSubmitLog: function() {
- try {
- var argc = arguments.length;
- var step = (argc > 0) ? arguments[0] : "";
- var desc = (argc > 1) ? arguments[1] : "";
- var url = (argc > 2) ? arguments[2] : "";
- if (typeof PTID != "undefined" && PTID.length > 0) {
- desc += ",PTID:" + PTID;
- }
- Logger.WriteStepLog(step, this.Guid(), this.SessionID(), this.ProcessTime(), desc, url);
- $f(this.HistoryControl).value = "1";
-
- if (step == "step2submit") {
- $f(this.HistoryControl).value = "1,1";
- }
- this.SetTimer();
- }
- catch (e) {
- }
- },
- SetTimer: function() {
- if (Timer && typeof Timer != "undefined") {
- Timer.Reset();
- }
- },
- DirectOpenLog: function() {
- try {
- var argc = arguments.length;
- var step = (argc > 0) ? arguments[0] : "";
- var desc = (argc > 1) ? arguments[1] : "";
- if (typeof PTID != "undefined" && PTID.length > 0) {
- desc += ",PTID:" + PTID;
- }
- this.AppSys = 2;
- Logger.WriteStepLog(step, this.Guid(), this.SessionID(), this.ProcessTime(), desc);
- if (step != Step.step1) {
- this.SetTimer();
- }
- }
- catch (e) {
- }
- }
- };
- var $f = function(name) {
- return document.getElementById(name);
- }
- window.onerror = function GetErrors(error) {
- try {
- var msg;
- for (var i = 0; i < arguments.length; i++) {
- if (i == 0 || i == 2) {
- msg += " | " + arguments[i];
- }
- }
- if (msg.length > 0 && typeof Logger != ‘undefined‘) {
- Logger.WriteStepLog(‘syserror‘, ‘-‘, ‘-‘, ‘‘, msg);
- }
- window.onerror = null;
- return true;
- } catch (e) { };
- }
2、时间统计
通过在页面放置计时器,计算当前视图下用户的停留时间。
示例:
- var up, down;
- var cmin1, csec1, clock;
- var Timer = {
- Debug: false,
- BindControl: ‘inputTimer‘,
- StartTime: ‘‘,
- EndTime: ‘‘,
- StartTimer: function() {
- if (!$f(this.BindControl)) return;
- if ($f(this.BindControl).value != "") return;
-
- cmin1 = 0;
- csec1 = 0;
-
-
-
-
-
-
-
-
-
-
- this.Repeat();
- },
- SetValue: function() {
- var html = $f(this.BindControl).value;
- if (html != null && html.length > 0) SetCookie("Timer", html);
- },
- Minutes: function(data) {
- for (var i = 0; i < data.length; i++) if (data.substring(i, i + 1) == ":") break;
- return (data.substring(0, i));
- },
- Seconds: function(data) {
- for (var i = 0; i < data.length; i++) if (data.substring(i, i + 1) == ":") break;
- return (data.substring(i + 1, data.length));
- },
- Display: function(min, sec) {
- var disp = "";
- if (min <= 9) disp += "0" + min + ":";
- else disp += min + ":";
- if (sec <= 9) disp += "0" + sec;
- else disp += sec;
- return (disp);
- },
- Repeat: function() {
- csec1++;
- if (csec1 == 60) { csec1 = 0; cmin1++; }
- $f(this.BindControl).value = this.Display(cmin1, csec1);
- if (this.Debug) $f("inputDebug").value = this.Display(cmin1, csec1);
- clock = window.setTimeout(function() { Timer.Repeat() }, 1000);
- },
-
- Reset: function() {
- $f(this.BindControl).value = "";
- window.clearTimeout(clock);
- Timer.StartTimer();
- },
- AddTrigger: function() {
- var list = document.getElementsByTagName("INPUT");
- for (var i = 0; i < list.length; i++) {
- if (list[i].type.toUpperCase() == ‘TEXT‘) {
- if (list[i].addEventListener) {
- list[i].addEventListener("keyup", function() { Timer.StartTimer(); }, false);
- }
- else {
- list[i].attachEvent("onkeyup", function() { Timer.StartTimer(); });
- }
- }
- }
- }
- };
- if (document.all) {
- window.attachEvent("onload", function() { Timer.AddTrigger() });
- }
- else {
- window.addEventListener("load", function() { Timer.AddTrigger() }, false);
- }
- if (Timer.Debug) {
- if (!document.getElementById("inputDebug")) {
- document.write("<input type=‘text‘ id=‘inputDebug‘ />");
- }
- }
3、异步记录
将收集到的数据通过GET、POST异步的方式发送到目标服务器
示例:
- var Step =
- {
-
- step1: "step1",
- step2: "step2",
- step3: "step3",
-
- step1submit: "step1submit",
- step2submit: "step2submit",
- step3submit: "step3submit",
- step3resubmit: "step3resubmit",
-
- success:"success",
- succret: "succret",
- step1ret: "step1ret",
- step2ret: "step2ret",
- step3ret: "step3ret",
-
- error:"error",
- errstep1: "errstep1",
- errstep2: "errstep2",
- errstep3: "errstep3",
- errstep1ret: "errstep1ret",
- errstep2ret: "errstep2ret",
- errstep3ret: "errstep3ret",
-
- loginb1: "loginb1",
- loginc1: "loginc1",
- loginbind: "loginbind",
- step1login: "step1login",
-
- bind: "bind",
- mobile: "mobile",
- password: "password",
- cancelbind: "cancelbind",
- Login: "Login",
- querydeposit: "querydeposit",
- querycardbalance: "querycardbalance",
- clickkf: "clickkf",
- closekf: "closekf",
- clickaccount1: "clickaccount1",
- clickaccount2: "clickaccount2"
- };
- var Environment = { Dev: "http://dev.xxx.com", Test: "http://test.xxx.com", Official: "http://www.xxx.com" }
- var Trace = {
- AutoSubmit: false,
- Parameter: {
- TraceType: ‘‘,
- Guid: ‘0‘,
- SessionID: ‘‘,
- PageUrl: ‘‘,
- Description: ‘‘,
- ProcessTime: ‘‘,
- IsNewSite: false,
- AppSys: 1,
- ClientIP: ‘‘,
- Environment: Environment.Official,
- Extend: {}
- },
- MyAjax: function() {
- this.xml = false;
- this.GetXmlHttp = function() {
- if (!this.xml && typeof XMLHttpRequest != ‘undefined‘) {
- this.xml = new XMLHttpRequest();
- }
- else {
- var MSXML = [‘MSXML2.XMLHTTP.5.0‘, ‘MSXML2.XMLHTTP.4.0‘, ‘MSXML2.XMLHTTP.3.0‘, ‘MSXML2.XMLHTTP‘, ‘Microsoft.XMLHTTP‘];
- for (var i = 0; i < MSXML.length; i++) {
- try {
- this.xml = new ActiveXObject(MSXML[i]);
- break;
- }
- catch (e) {
- }
- }
- }
- }
- this.GetXmlHttp();
- var xmlHttp = this.xml;
- var ajax = this;
- var callBack = null;
- this.updatePage = function() {
- if (xmlHttp.readyState == 4) {
- var response = xmlHttp.responseText;
- if (callBack != null && typeof callBack == "function") {
- callBack(response);
- }
- }
- }
- this.toQueryString = function(json) {
- var query = "";
- if (json != null) {
- for (var param in json) {
- query += param + "=" + escape(json[param]) + "&"
- }
- }
- return query;
- }
-
- this.invoke = function(params, pageCallBack, method) {
- if (xmlHttp) {
- var query = "";
- query += this.toQueryString(params);
- query = query.substring(0, query.length - 1);
-
-
- callBack = pageCallBack;
- if (method != null && method.toUpperCase() == "GET") {
- var url = params.Environment + "/Trace.aspx?" + query;
- xmlHttp.onreadystatechange = ajax.updatePage;
- xmlHttp.open("GET", url, true);
- xmlHttp.setRequestHeader("TraceAjax-Ver", "ver1.0");
- xmlHttp.send(null);
- }
- else if (method != null && method.toUpperCase() == "POST") {
- var url = params.Environment + "/Trace.aspx";
-
- xmlHttp.onreadystatechange = ajax.updatePage;
- xmlHttp.open("POST", url, true);
- xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
- xmlHttp.setRequestHeader("TraceAjax-Ver", "ver1.0");
- xmlHttp.send(query);
- }
- else {
- Trace.CreateTraceImg();
- document.getElementById("traceImg").src = params.Environment + "/Trace.aspx?a=" + Math.random(1000000000) + "&" + query;
- }
- }
- }
- },
- CreateTraceImg: function() {
- if (!document.getElementById("traceImg")) {
- document.write("<img id=\"traceImg\" style=‘display:none‘ />");
-
-
-
-
- }
- },
- Submit: function(params, pageCallBack, method) {
- try {
- var ajax = new Trace.MyAjax();
-
-
-
-
-
-
- ajax.invoke(params, pageCallBack, method);
- }
- catch (e) {
- }
- }
- };
- Trace.CreateTraceImg();
4、后端数据分析
结合前台收集的用户数据,后台初步可以完成,每一个页面的打开次数、占用时长,提交率、以及后台业务流的成功率等,通过报表形式展示数据分析界面,这样就可以监控用户行为异常、监控系统波动以及影响区域。
5、扩展
通过记录来源地址,可以更详尽的分析用户行为的流程。
通过追加页面元素的点击情况,从而计算点击率。
虽然服务器端也可以做到这些过程,但需求在不同的过程中插入众多的日志记录,进而POST到服务器端,过于繁冗!
另外跟踪服务器可对来源的数据请求验证其合法性,以及是否授权。
*注意:在Tracer的过程中,如遇采用系统方法如:绑定事件window.onload,需要注意不用覆盖了方法,避免与应用的页面冲突,可以通过来添加事件监听,eg:
AddTrigger: function() {
- var list = document.getElementsByTagName("INPUT");
- for (var i = 0; i < list.length; i++) {
- if (list[i].type.toUpperCase() == ‘TEXT‘) {
- if (list[i].addEventListener) {
- list[i].addEventListener("keyup", function() { Timer.StartTimer(); }, false);
- }
- else {
- list[i].attachEvent("onkeyup", function() { Timer.StartTimer(); });
- }
- }
- }
- }
6、关于脚本压缩
推荐采用JSA压缩工具,原因:稳定、可靠、压缩质量有保证
不过需要大家安装一下JAVA RUNTIME
Web网站行为跟踪
标签:des style http io ar os java sp for
原文地址:http://www.cnblogs.com/zgb2014/p/4089512.html