具体步骤分为数据采集脚本,数据收取服务,数据分析脚本,数据存储服务javascript
采集脚本通常有两种形式,一种是简单的页面插入一个图片进行请求,一种是复杂的动态生成js标签,引入一段js(这时采集服务器会网往客户端写cookie),js采集浏览器数据与cookie,而后发送请求。php
数据收取服务通常为web服务,能够是apache,nginx,或者swoole,这里主要看采集的压力,适当作负载均衡,能够爱脚本端作,也能够在服务端作,注意客户端ip的穿透。html
脚本分析可使用任何脚本,例如php,python。html5
数据存储分为两部,一个是采集数据的存储,一个是分析以后的数据的存储,通常来说原始数据是需呀保留的,因此原始数据采集可使用文本保存在单机,或者使用redis等可固话的存储容器保存。java
选用不一样的形式对扩展之后的服务有必定的影响,暂且不谈,在pv/uv只有几百万的站点,或者几千万的站点web服务压力基本不大,天天的原始数据存储会有几百M。python
细节上可使用不一样的技术,例如加入memcached缓存,使用多进程多线程等nginx
我使用的方案是使用nginx作采集web服务器,使用js脚本采集数据,采集的数据按五分钟分500个文件存储避免文本的冲突,而后php五分钟按期处理数据,统计结果记入redis保存。c++
js采集脚本以下:web
(function () { var c = { id: '{$sid}', dm: [ {$dm} ], nv: {$nv}, vdur: {$vdur}, age: {$age}, rec: {$rec}, uid: {$uid}, cf : {$cf} }; var l = !0, m = null, n = !1; var p = function () { function a(a) { /["\\\x00-\x1f]/.test(a) && (a = a.replace(/["\\\x00-\x1f]/g, function (a) { var b = d[a]; if (b) return b; b = a.charCodeAt(); return '\\u00' + Math.floor(b / 16) .toString(16) + (b % 16) .toString(16) })); return '"' + a + '"' } function b(a) { return 10 > a ? '0' + a : a } var d = { '': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"': '\\"', '\\': '\\\\' }; return function (d) { switch (typeof d) { case 'undefined': return 'undefined'; case 'number': return isFinite(d) ? String(d) : 'null'; case 'string': return a(d); case 'boolean': return String(d); default: if (d === m) return 'null'; if (d instanceof Array) { var f = [ '[' ], h = d.length, k, g, u; for (g = 0; g < h; g++) switch (u = d[g], typeof u) { case 'undefined': case 'function': case 'unknown': break; default: k && f.push(','), f.push(p(u)), k = 1 } f.push(']'); return f.join('') } if (d instanceof Date) return '"' + d.getFullYear() + '-' + b(d.getMonth() + 1) + '-' + b(d.getDate()) + 'T' + b(d.getHours()) + ':' + b(d.getMinutes()) + ':' + b(d.getSeconds()) + '"'; k = [ '{' ]; for (h in d) if (Object.prototype.hasOwnProperty.call(d, h)) switch (g = d[h], typeof g) { case 'undefined': case 'unknown': case 'function': break; default: f && k.push(','), f = 1, k.push(p(h) + ':' + p(g)) } k.push('}'); return k.join('') } } }(); function q(a, b) { var d = a.match(RegExp('(^|&|\\?|#)(' + b + ')=([^&#]*)(&|$|#)', '')); return d ? d[3] : m } function v(a) { return (a = (a = a.match(/^(https?:\/\/)?([^\/\?#]*)/)) ? a[2].replace(/.*@/, '') : m) ? a.replace(/:\d+$/, '') : a }; function w(a, b) { if (window.sessionStorage) try { window.sessionStorage.setItem(a, b) } catch (d) { } } function x(a) { return window.sessionStorage ? window.sessionStorage.getItem(a) : m }; function y(a, b, d) { var e; d.f && (e = new Date, e.setTime(e.getTime() + d.f)); document.cookie = a + '=' + b + (d.domain ? '; domain=' + d.domain : '') + (d.path ? '; path=' + d.path : '') + (e ? '; expires=' + e.toGMTString() : '') + (d.r ? '; secure' : '') }; function z(a, b) { var d = new Image, e = 'mini_yp_log_' + Math.floor(2147483648 * Math.random()) .toString(36); window[e] = d; d.onload = d.onerror = d.onabort = function () { d.onload = d.onerror = d.onabort = m; d = window[e] = m; b && b(a) }; d.src = a }; var A; function D() { if (!A) try { A = document.createElement('input'), A.type = 'hidden', A.style.display = 'none', A.addBehavior('#default#userData'), document.getElementsByTagName('head') [0].appendChild(A) } catch (a) { return n } return l } function E(a, b, d) { var e = new Date; e.setTime(e.getTime() + d || 31536000000); try { window.localStorage ? (b = e.getTime() + '|' + b, window.localStorage.setItem(a, b)) : D() && (A.expires = e.toUTCString(), A.load(document.location.hostname), A.setAttribute(a, b), A.save(document.location.hostname)) } catch (f) { } } function H(a) { if (window.localStorage) { if (a = window.localStorage.getItem(a)) { var b = a.indexOf('|'), d = a.substring(0, b) - 0; if (d && d > (new Date) .getTime()) return a.substring(b + 1) } } else if (D()) try { return A.load(document.location.hostname), A.getAttribute(a) } catch (e) { } return m }; function I(a, b, d) { a.attachEvent ? a.attachEvent('on' + b, function (b) { d.call(a, b) }) : a.addEventListener && a.addEventListener(b, d, n) }; function N(a, b) { return '[object ' + b + ']' === { }.toString.call(a) }; function Z(a, b) { a = '.' + a.replace(/:\d+/, ''); b = '.' + b.replace(/:\d+/, ''); var d = a.indexOf(b); return - 1 < d && d + b.length == a.length } function wa(a, b) { a = a.replace(/^https?:\/\//, ''); return 0 == a.indexOf(b) } function Y(a) { for (var b = 0; b < c.dm.length; b++) if ( - 1 < c.dm[b].indexOf('/')) { if (wa(a, c.dm[b])) return l } else { var d = v(a); if (d && Z(d, c.dm[b])) return l } return n } function ra(a) { for (var b = [ ], d = 0, e = R.length; d < e; d++) { var f = R[d], h = a.a[f]; 'undefined' != typeof h && '' !== h && b.push(f + '=' + encodeURIComponent(h)) } d = a.a.et; (0 === d || 90 === d) && a.a.rt && b.push('rt=' + encodeURIComponent(a.a.rt)); return b.join('&') } function na() { var a = 'Yp_cv_' + c.id; try { if (y(a, '', { domain: la(), path: ma(), f: - 1 }), window.sessionStorage && window.sessionStorage.removeItem(a), window.localStorage) window.localStorage.removeItem(a); else if (D()) try { A.load(document.location.hostname), A.removeAttribute(a), A.save(document.location.hostname) } catch (b) { } } catch (d) { } } function ma() { for (var a = 0, b = c.dm.length; a < b; a++) { var d = c.dm[a]; if ( - 1 < d.indexOf('/') && wa(document.location.href, d)) return d.replace(/^[^\/]+(\/.*)/, '$1') + '/' } return '/' } function la() { for (var a = document.location.hostname, b = 0, d = c.dm.length; b < d; b++) if (Z(a, c.dm[b])) return c.dm[b].replace(/(:\d+)?[\/\?#].*/, ''); return a } function pa() { var a = x('Yp_unsent_' + c.id); if (a) for (var a = a.split(','), b = 0, d = a.length; b < d; b++) z(Q + '//' + decodeURIComponent(a[b]) .replace(/^https?:\/\//, ''), function (a) { X(a) }) } function X(a) { var b = x('Yp_unsent_' + c.id) || ''; b && ((b = b.replace(RegExp(encodeURIComponent(a.replace(/^https?:\/\//, '')) .replace(/([\*\(\)])/g, '\\$1') + '(%26u%3D[^,]*)?,?', 'g'), '') .replace(/,$/, '')) ? w('Yp_unsent_' + c.id, b) : window.sessionStorage && window.sessionStorage.removeItem('Yp_unsent_' + c.id)) } function qa(a, b) { var d = x('Yp_unsent_' + c.id) || '', e = a.a.u ? '' : '&u=' + encodeURIComponent(document.location.href), d = encodeURIComponent(b.replace(/^https?:\/\//, '') + e) + (d ? ',' + d : ''); w('Yp_unsent_' + c.id, d) } (function () { function a() { if (!a.b) { a.b = l; for (var b = 0, d = e.length; b < d; b++) e[b]() } } function b() { try { document.documentElement.doScroll('left') } catch (d) { setTimeout(b, 1); return } a() } var d = n, e = [ ], f; document.addEventListener ? f = function () { document.removeEventListener('DOMContentLoaded', f, n); a() } : document.attachEvent && (f = function () { 'complete' === document.readyState && (document.detachEvent('onreadystatechange', f), a()) }); (function () { if (!d) if (d = l, 'complete' === document.readyState) a.b = l; else if (document.addEventListener) document.addEventListener('DOMContentLoaded', f, n), window.addEventListener('load', a, n); else if (document.attachEvent) { document.attachEvent('onreadystatechange', f); window.attachEvent('onload', a); var e = n; try { e = window.frameElement == m } catch (k) { } document.documentElement.doScroll && e && b() } }) (); return function (b) { a.b ? b() : e.push(b) } }) () .b = n; function ta() { this.d = this.j = (new Date) .getTime(); this.i = 0; 'object' == typeof document.onfocusin ? (I(document, 'focusin', $(this)), I(document, 'focusout', $(this))) : (I(window, 'focus', $(this)), I(window, 'blur', $(this))) } function $(a) { return function (b) { if (!(b.target && b.target != window)) { if ('blur' == b.type || 'focusout' == b.type) a.i += (new Date) .getTime() - a.d; a.d = (new Date) .getTime() } } } function sa(a) { return function () { a.a.nv = 0; a.a.st = 4; a.a.et = 3; a.a.ep = (new Date) .getTime() - a.e.j + ',' + ((new Date) .getTime() - a.e.d + a.e.i); W(a) } } function W(a) { a.a.rnd = Math.round(2147483647 * Math.random()); a.a.api = a.a.api || a.c ? a.a.api + '_' + a.c : ''; var b = Q + '//{$callurl}?' + ra(a); a.a.api = 0; a.c = 0; qa(a, b); z(b, function (a) { X(a) }) } var aa = navigator.cookieEnabled, ba = navigator.javaEnabled(), ha = navigator.language || navigator.browserLanguage || navigator.systemLanguage || navigator.userLanguage || '', ia = (window.screen.width || 0) + 'x' + (window.screen.height || 0), ja = window.screen.colorDepth || 0; var O = 0, P = Math.round( + new Date / 1000), Q = 'https:' == document.location.protocol ? 'https:' : 'http:', //参数数组 //cc : 是否支持写数据到浏览器(cookie,sessionStorage,localStorage,userData) //ck : 是否支持cookie //cl : 浏览器颜色位数 //ds : 浏览器分辨率 //ep : 事件描述 //et : 事件类型,默认是0为通常统计,3为关闭事件 //fl : flash版本 //ja : 是否支持java //ln : 浏览器语言 //lt : 30天内的最后一次首次访问的时间,首次访问为空 //nv : 是否开启一次新访问,能够理解为uv,可是不是独立访客 //rnd: 随机数 //si : 统计id,站点标示 //st : 外域来源为3,本域为1,4 //su : 来源url //v : 当前脚本版本 //cv : 用户自定义数据 //lv : 当月新访问<4 为2 ,=4 为3, =0 为1,能够理解为客户新访问频次 //api: 未知,与事件相关 //tt : 站点title //u : 站点url //cf : m点 1,站点0 //uid : 会员id //pt : 平台 //ocu : 操做系统 //ua : 浏览器类型 R = 'cc ck cl ds ep et fl ja ln lt nv rnd si st su v cv lv api tt u gt cf uid pt ocu ua'.split(' '); function V() { if ('undefined' == typeof window['_yphm_loaded_' + c.id]) { window['_yphm_loaded_' + c.id] = l; var a = this; a.a = { }; a.q = [ ]; a.p = { push: function () { a.k.apply(a, arguments) } }; a.c = 0; a.h = n; ka(a) } } V.prototype = { getData: function (a) { try { var b = RegExp('(^| )' + a + '=([^;]*)(;|$)') .exec(document.cookie); return (b ? b[2] : m) || x(a) || H(a) } catch (d) { } }, setData: function (a, b, d) { try { y(a, b, { domain: la(), path: ma(), f: d }), d ? E(a, b, d) : w(a, b) } catch (e) { } }, k: function (a) { if (N(a, 'Array')) { var b = function (a) { return a.replace ? a.replace(/'/g, '\'0') .replace(/\*/g, '\'1') .replace(/!/g, '\'2') : a }, d = function (a) { for (var b in a) if ({ }.hasOwnProperty.call(a, b)) { var e = a[b]; N(e, 'Object') || N(e, 'Array') ? d(e) : a[b] = String(e) } }; switch (a[0]) { case '_trackPageview': if (1 < a.length && a[1].charAt && '/' == a[1].charAt(0)) { this.a.api |= 4; this.a.et = 0; this.a.ep = ''; this.h ? (this.a.nv = 0, this.a.st = 4) : this.h = l; var b = this.a.u, e = this.a.su; this.a.u = Q + '//' + document.location.host + a[1]; this.a.su = document.location.href; W(this); this.a.u = b; this.a.su = e } break; case '_trackEvent': 2 < a.length && (this.a.api |= 8, this.a.nv = 0, this.a.st = 4, this.a.et = 4, this.a.ep = b(a[1]) + '*' + b(a[2]) + (a[3] ? '*' + b(a[3]) : '') + (a[4] ? '*' + b(a[4]) : ''), W(this)); break; case '_setCustomVar': if (4 > a.length) break; var e = a[1], f = a[4] || 3; if (0 < e && 6 > e && 0 < f && 4 > f) { this.c++; for (var h = (this.a.cv || '*') .split('!'), k = h.length; k < e - 1; k++) h.push('*'); h[e - 1] = f + '*' + b(a[2]) + '*' + b(a[3]); this.a.cv = h.join('!'); a = this.a.cv.replace(/[^1](\*[^!]*){2}/g, '*') .replace(/((^|!)\*)+$/g, ''); '' !== a ? this.setData('Yp_cv_' + c.id, encodeURIComponent(a), c.age) : na() } break; case '_trackOrder': a = a[1]; N(a, 'Object') && (d(a), this.a.api |= 16, this.a.nv = 0, this.a.st = 4, this.a.et = 94, this.a.ep = p(a), W(this)); break; case '_trackMobConv': if (a = { webim: 1, tel: 2, map: 3, sms: 4, callback: 5, share: 6 } [ a[1] ]) this.a.api |= 32, this.a.et = 93, this.a.ep = a, W(this); break; case '_trackRTPageview': a = a[1]; N(a, 'Object') && (d(a), a = p(a), 512 >= encodeURIComponent(a) .length && (this.a.api |= 64, this.a.rt = a)); break; case '_trackRTEvent': a = a[1], N(a, 'Object') && (d(a), a = p(a), 1024 >= encodeURIComponent(a) .length && (b = this.a.rt, this.a.api |= 128, this.a.et = 90, this.a.rt = a, W(this), this.a.rt = b)) } } } }; function ka(a) { try { var b, d, e, f, h, k, g; O = a.getData('Yp_lpvt_' + c.id) || 0; 13 == O.length && (O = Math.round(O / 1000)); if (document.referrer) { var u = n; if (Y(document.referrer) && Y(document.location.href)) u = l; else var oa = v(document.referrer), u = Z(oa || '', document.location.hostname); d = u ? P - O > c.vdur ? 1 : 4 : 3 } else d = P - O > c.vdur ? 1 : 4; b = 4 != d ? 1 : 0; if (k = a.getData('Yp_lvt_' + c.id)) { g = k.split(','); for (var F = g.length - 1; 0 <= F; F--) 13 == g[F].length && (g[F] = '' + Math.round(g[F] / 1000)); for (; 2592000 < P - g[0]; ) g.shift(); h = 4 > g.length ? 2 : 3; for (1 === b && g.push(P); 4 < g.length; ) g.shift(); k = g.join(','); f = g[g.length - 1] } else k = P, f = '', h = 1; a.setData('Yp_lvt_' + c.id, k, c.age); a.setData('Yp_lpvt_' + c.id, P); e = P == a.getData('Yp_lpvt_' + c.id) ? '1' : '0'; if (0 == c.nv && Y(document.location.href) && ('' == document.referrer || Y(document.referrer))) b = 0, d = 4; a.a.nv = b; a.a.st = d; a.a.cc = e; a.a.lt = f; a.a.lv = h; a.a.si = c.id; a.a.uid = c.uid; a.a.cf = c.cf; a.a.su = document.referrer; a.a.u = document.location.href; a.a.pt = navigator.platform; var ua = navigator.userAgent.toLowerCase(); var s; if(s = ua.match(/msie ([\d.]+)/)) a.a.ua = 'IE' + s[1]; else if(s = ua.match(/firefox\/([\d.]+)/)) a.a.ua = 'Firefox' + s[1]; else if(s = ua.match(/chrome\/([\d.]+)/))a.a.ua = 'Chrome' + s[1]; else if(s = ua.match(/opera.([\d.]+)/)) a.a.ua = 'Opera' + s[1]; else if(s = ua.match(/version\/([\d.]+).*safari/)) a.a.ua = 'Safari' + s[1]; else a.a.ua = 'unknown'; a.a.ocu = navigator.oscpu; a.a.ds = ia; a.a.cl = ja + '-bit'; a.a.ln = ha; a.a.ja = ba ? 1 : 0; a.a.ck = aa ? 1 : 0; var J = a.a; b = ''; if (navigator.plugins && navigator.mimeTypes.length) { var B = navigator.plugins['Shockwave Flash']; B && B.description && (b = B.description.replace(/^.*\s+(\S+)\s+\S+$/, '$1')) } else if (window.ActiveXObject) try { var ca = new ActiveXObject('ShockwaveFlash.ShockwaveFlash'); ca && (b = ca.GetVariable('$version')) && (b = b.replace(/^.*\s+(\d+),(\d+).*$/, '$1.$2')) } catch (ya) { } J.fl = b; a.a.v = '1.0.0'; a.a.cv = decodeURIComponent(a.getData('Yp_cv_' + c.id) || ''); (a.a.tt = document.title || '') //屏蔽不是新uv不记录tt //1 == a.a.nv && (a.a.tt = document.title || ''); //暂时不清楚,18touch里没有看到这个参数 a.a.api = 0; //var G = document.location.href; //a.a.cm = q(G, 'hmmd') || ''; 0 == a.a.nv ? pa() : X('.*'); if (c.rec) a.a.nv ? (a.g = encodeURIComponent(document.referrer), window.sessionStorage ? w('Yp_from_' + c.id, a.g) : E('Yp_from_' + c.id, a.g, 86400000)) : a.g = (window.sessionStorage ? x('Yp_from_' + c.id) : H('Yp_from_' + c.id)) || ''; a.e = new ta; //I(window, 'beforeunload', sa(a)); var t = window._hmt; if (t && t.length) for (r = 0; r < t.length; r++) { var C = t[r]; switch (C[0]) { case '_setAccount': 1 < C.length && /^[0-9a-z]{32}$/.test(C[1]) && (a.a.api |= 1, window._yphm_account = C[1]); break; case '_setAutoPageview': if (1 < C.length) { var U = C[1]; if (n === U || l === U) a.a.api |= 2, window._yphm_autoPageview = U } } } if ('undefined' === typeof window._yphm_account || window._yphm_account === c.id) { window._yphm_account = c.id; var M = window._hmt; if (M && M.length) for (var t = 0, xa = M.length; t < xa; t++) a.k(M[t]); window._hmt = a.p } if ('undefined' === typeof window._yphm_autoPageview || window._yphm_autoPageview === l) a.h = l,a.a.et = 0,a.a.ep = '',W(a) } catch (ga) { a = [ ], a.push('si=' + c.id), a.push('n=' + encodeURIComponent(ga.name)), a.push('m=' + encodeURIComponent(ga.message)), a.push('r=' + encodeURIComponent(document.referrer)), z(Q + '//{$callurl}?' + a.join('&')) } } new V; }) ();
脚本的函数说明以下:redis
//定义p方法,将传入的参数转换为字符串形式
//定义q方法,从字符串a里找出含有字符串b的值,若是没有则为null,貌似是从url请求参数里获取值
//定义v方法,取url中协议后的第一个/以前的内容并将端口号去掉,例如http://www.18touch.com:999/ 过滤以后获得www.18touch.com
//定义w方法,在html5的属性sessionStorage里存放window.sessionStorage[a]=b;,百度统计存放的是访问时间,估计用于计算回话时间
//定义x方法,在html5的属性sessionStorage里取出w方法定义的key为a的值,不支持这个属性返回null
//定义y方法,设置cookie,a=b,cookie的属性在d对象里面
//定义z方法,请求a地址,并作记录,在请求完成,出错,拒绝以后,重置。若是定义了回调b方法,则执行b(a);
//定义D方法,全局变量A为空则执行将A变成一个userdata对象,用于ie浏览器储存数据,报错返回false;全局变量A不为空返回true;
//定义E方法,若是支持window.localStorage,则保持window.localStorage[a]=now+d|b,若是不支持再看是否支持userdata,若是支持,在域名下使用userdata存储a=b,过时时间为now+d
//定义H方法,若是没有过时的话取出从E方法存储的key为a的值,不然返回null。
//定义I方法,在a元素上绑定事件b,处理函数为d
//定义N方法,判读a的类型是否为b
//定义V方法,启动统计功能
//定义V原型方法,
//定义pa方法,从sessionStorage里取Hm_unsent_字符串,按,分隔,依次调用z方法发送请求,并调用回调函数X
//定义X方法,用做请求后的回调,去掉sessionStorage里的Hm_unsent_字符串里的请求url,若是Hm_unsent_为空,删除Hm_unsent_
//定义qa方法,在sessionStorage里的key:Hm_unsent_后添加url b,若是a.a.u存在,后面还要添加&u=当前url的后缀
//定义W方法,调用qa往sessionStorage的Hm_unsent_里存储url:hm.baidu.com/hm.gif,调用z方法发送请求,并执行回调X
//定义sa方法,返回一个初始化a.a数组,并执行触发请求的方法,在window.beforeunload触发,关闭页面时触发
//定义ka方法,执行信息收集与消息发送,以及事件监听
//定义ra方法,组装R请求的字符串,数据从a.a数组里面获取
//定义na方法,从cookie,sessionStorage,localStorage,usedata删除Hm_cv_
//定义ma方法,若是当前href在以域名配置数组里的开头,返回/以及以后的部分
//定义la方法,取当前域名,若是域名数组里有当前域名结尾的,返回域名数组里的配置项,不然返回当前域名
//定义Y方法,判断url a的域是否在域数组里
//定义wa方法,判断字符串b是不是url a的开头
//定义Z方法,判断去除端口号以后的url b,是不是 url a的结尾部分
//定义ta方法,绑定window的focusin,focusout事件,须要浏览器支持a.j为加载后的时间
//定义$方法,检测window的focus与blur事件,计算a.d为最后操做时间,a.i为操做累计时间
WEB服务段的输出这段脚本的php为:
error_reporting(0);
date_default_timezone_set("PRC");
$environment = get_cfg_var('app_flow_develop') ? get_cfg_var('app_flow_develop') : 3;
define('BASEPATH',dirname(dirname(__FILE__)));
switch($environment){
case 1 :
require BASEPATH . DIRECTORY_SEPARATOR . 'conf' . DIRECTORY_SEPARATOR . 'config.product.php';
break;
case 2 :
require BASEPATH . DIRECTORY_SEPARATOR . 'conf' . DIRECTORY_SEPARATOR . 'config.product.php';
break;
default:
require BASEPATH . DIRECTORY_SEPARATOR . 'conf' . DIRECTORY_SEPARATOR . 'config.develop.php';
break;
}
$sid = addslashes($_GET['sid']);
$uid = isset($_GET['uid'])? addslashes($_GET['uid']) : null;
$cf = isset($_GET['cf'])? addslashes($_GET['cf']) : null;
if(array_key_exists($sid,$config)){
//检查帐户,没有就写一个
if(!isset($_COOKIE['YPTJACCOUNT'])){
setcookie('YPTJACCOUNT',$sid,time () + 3600 * 24 * 365 * 5 , "/" , $tjdomain);
}
//检查UV标识,没有就种一个
if(!isset($_COOKIE['YPTJUUID'])){
$now = time ();
$pretime = strtotime('tomorrow') - $now;
setcookie('YPTJUUID',uniqid(true),$now + $pretime , "/" , $tjdomain);
}
//有会员则覆盖js配置
if($uid){
$config[$sid]['uid'] = $uid;
}
//判断网站仍是m站
if($cf){
switch($cf){
case 1 : $config[$sid]['cf'] = 1;break;
default : $config[$sid]['cf'] = 0;break;
}
}
//判断js缓存
$lastmodifytime = filemtime(BASEPATH . DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR .'yptj.js');
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
$browserCachedCopyTimestamp = strtotime(preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE']));
//if($browserCachedCopyTimestamp >= $lastmodifytime){
if($browserCachedCopyTimestamp + $interval > time()){
header("http/1.1 304 Not Modified");
exit;
}
}
//header ("Last-Modified: " . gmdate ('r', $lastmodifytime));
//header ("Expires: " . gmdate ("r", ($lastmodifytime + $interval)));
header ("Last-Modified: " . gmdate ('r', time()));
header ("Expires: " . gmdate ("r", (time() + $interval)));
header ("Cache-Control: max-age={$interval}");
$js = file_get_contents(BASEPATH . DIRECTORY_SEPARATOR . 'js' . DIRECTORY_SEPARATOR .'yptj.js');
$js = str_replace($replace_a,$config[$sid],$js);
echo $js;
exit;
}else{
exit;
}
web页面插入的动态脚本为:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>超好玩</title> </head> <body> hello,index <script type="text/javascript"> //0c998ee80e953443caf0cf6b5ba7b5db var _yphmProtocol = (("https:" == document.location.protocol) ? "https://" : "http://"); document.write(unescape('%3Cscript src="' + _yphmProtocol + 'hm.tj.com/h.js%3F0c998ee80e953443caf0cf6b5ba7b5db" type="text/javascript"%3E%3C/script%3E')); </script> </body> </html>
配置文件为
//接收地址 $tjdomain = 'hm.tj.com'; //统计帐号配置信息 $config = array( '0c998ee80e953443caf0cf6b5ba7b5db'=>array( '0c998ee80e953443caf0cf6b5ba7b5db', "{$tjdomain}/hm.php", "'18touch.com'", -1, 1800000, 31536000000, 0, 0, 0 ), ); //js文件过时时间 $interval = 60 * 60 * 24 * 7; // 1 week //置换数组 $replace_a = array( '{$sid}', '{$callurl}', '{$dm}', '{$nv}', '{$vdur}', '{$age}', '{$rec}', '{$uid}', '{$cf}' ); //日志数据的记录目录 $LOG_BASE = BASEPATH . DIRECTORY_SEPARATOR . "data"; //redis数据库配置 $REDIS_IP = '127.0.0.1'; $REDIS_PORT = 6379;