具體步驟分爲數據採集腳本,數據收取服務,數據分析腳本,數據存儲服務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;