/*! * Dossm MarTech v2.0.0 * Copyright 2006 - 2019 Wintour,Inc. * Description : Dossm MarTech 网页标签、停留时长统计 * Date : 2019-09-18 **/ // 当前目标页面地址(请求当前js的来源地址) var referer = ""; var _prefix = "__tp_f_"; var keyPrefix = ""; // 页面加载onload事件 window.addEventListener("load", function() { keyPrefix = _prefix + md5(referer); /** * 当前目标页面的加载时间、显示时间、初始的活跃时长 */ var timestamp = Date.parse(new Date()); window.localStorage.setItem(keyPrefix + "_onload", timestamp); window.localStorage.setItem(keyPrefix + "_onshow", timestamp); window.localStorage.setItem(keyPrefix + "_active", 0); // sites系统的写入参数 var cardSn = ""; var mobile = ""; var email = ""; var province = ""; var city = ""; var address = ""; var name = ""; var sex = ""; var company = ""; var title = ""; var tags = ""; // 通过IMG提交信息的请求地址 var url = "/ng/ng.png?ts=" + timestamp; /** * 当前页面浏览事件WEBSITE_BROWSE */ if (referer !== null && referer !== undefined && referer !== "") { url = url + "&r=" + encodeURIComponent(referer); } if (cardSn !== null && cardSn !== undefined && cardSn !== "") { url = url + "&cs=" + cardSn; } if (mobile !== null && mobile !== undefined && mobile !== "") { url = url + "&m=" + mobile; } if (email !== null && email !== undefined && email !== "") { url = url + "&e=" + email; } if (province !== null && province !== undefined && province !== "") { url = url + "&p=" + province; } if (city !== null && city !== undefined && city !== "") { url = url + "&c=" + city; } if (address !== null && address !== undefined && address !== "") { url = url + "&a=" + address; } if (name !== null && name !== undefined && name !== "") { url = url + "&n=" + name; } if (sex !== null && sex !== undefined && sex !== "") { url = url + "&s=" + sex; } if (company !== null && company !== undefined && company !== "") { url = url + "&co=" + company; } if (title !== null && title !== undefined && title !== "") { url = url + "&ti=" + title; } if (tags !== null && tags !== undefined && tags !== "") { url = url + "&t=" + tags; } /** * 当前cookie中保存的页面停留时长、活跃时长信息WEBSITE_BROWSE_PAGE_TIME */ var array = getMarTech2CookieKeyList(); if (array.length > 0) { // 拼接参数 var pageUrls = [], pageStamps = [], pageTimes = [], activeTimes = []; for (var i = 0; i < array.length; i++) { var k = _prefix + array[i]; var pu = getMarTech2Cookie(k + "_pu"); var ps = getMarTech2Cookie(k + "_ps"); var pt = getMarTech2Cookie(k + "_pt"); var at = getMarTech2Cookie(k + "_at"); pageUrls.push(pu); pageStamps.push(ps / 1000); pageTimes.push(pt / 1000); activeTimes.push(at / 1000); deleteMarTech2Cookie(k + "_pu"); deleteMarTech2Cookie(k + "_ps"); deleteMarTech2Cookie(k + "_pt"); deleteMarTech2Cookie(k + "_at"); } url = url + "&pu=" + encodeURIComponent(pageUrls.join(",")); url = url + "&ps=" + pageStamps.join(","); url = url + "&pt=" + pageTimes.join(","); url = url + "&at=" + activeTimes.join(","); } /** * 通过img提交上述信息 */ var ng = document.createElement("img"); var s = document.getElementsByTagName("body")[0]; ng.src = url; ng.style.display = "none"; s.insertBefore(ng, null); }, false); // 页面离开前onbeforeunload事件 window.addEventListener("beforeunload", function() { // 页面加载时间戳 var pageStamp = window.localStorage.getItem(keyPrefix + "_onload") ? window.localStorage.getItem(keyPrefix + "_onload") : 0; // 计算页面停留时长 var pageTime = Date.parse(new Date()) - pageStamp; // 本次活跃时长(当前时间戳 - 本次显示时间戳) var showStamp = window.localStorage.getItem(keyPrefix + "_onshow") ? window.localStorage.getItem(keyPrefix + "_onshow") : 0; var currentActiveTime = Date.parse(new Date()) - showStamp; // 页面的活跃时长累计 var activeTime = window.localStorage.getItem(keyPrefix + "_active") ? window.localStorage.getItem(keyPrefix + "_active") : 0; activeTime = activeTime + currentActiveTime; // 写入cookie(页面地址、加载时间戳、停留时长、活跃时长) setMarTech2Cookie(keyPrefix + "_pu", referer); setMarTech2Cookie(keyPrefix + "_ps", pageStamp); setMarTech2Cookie(keyPrefix + "_pt", pageTime); setMarTech2Cookie(keyPrefix + "_at", activeTime); }, false); /** * 页面可见性 (有兼容性。注:visibilitychange) * 记录页面显示状态 探测用户浏览情况 * [hiddenProperty description] * @type {String} */ var hiddenProperty = 'hidden' in document ? 'hidden' : 'webkitHidden' in document ? 'webkitHidden' : 'mozHidden' in document ? 'msHidden' : 'msHidden' in document ? 'msHidden' : null; var visibilityChangeEvent = hiddenProperty.replace(/hidden/i, 'visibilitychange'); // 页面可见性监听 document.addEventListener(visibilityChangeEvent, function() { // 当前页面是否隐藏 var isHidden = document[hiddenProperty]; if (isHidden) { // 本次活跃时长(当前时间戳 - 本次显示时间戳) var showStamp = window.localStorage.getItem(keyPrefix + "_onshow") ? window.localStorage.getItem(keyPrefix + "_onshow") : 0; var currentActiveTime = Date.parse(new Date()) - showStamp; // 页面的活跃时长累计 var activeTime = window.localStorage.getItem(keyPrefix + "_active") ? window.localStorage.getItem(keyPrefix + "_active") : 0; activeTime = activeTime + currentActiveTime; // 存储页面的活跃时长 window.localStorage.setItem(keyPrefix + "_active", activeTime); } else { // 本次页面的显示时间戳 var timestamp = Date.parse(new Date()); window.localStorage.setItem(keyPrefix + "_onshow", timestamp); } }, false); // 查询Cookie中复合页面停留时长key条件的所有key的数组 function getMarTech2CookieKeyList() { var reg = new RegExp(_prefix + ".{32}" + "_pu", "g"); var array = document.cookie.match(reg); var keyList = []; if (array) { for (var i = 0; i < array.length; i++) { var key = array[i]; var md5Key = key.substring(_prefix.length, key.length - 3); keyList.push(md5Key); } } return keyList; } // 设置Cookie(有效期30天,范围全网站) function setMarTech2Cookie(key, value) { // 有效期30天 var d = new Date(); d.setTime(d.getTime() + (30 * 24 * 3600 * 1000)); var expires = "expires=" + d.toGMTString(); // 设置Cookie,范围全网站 document.cookie = key + "=" + escape(value) + ";" + expires + ";path=/"; } // 读取Cookie function getMarTech2Cookie(key) { var str = "(^| )" + key + "=([^;]*)(;|$)"; var reg = new RegExp(str); var array = document.cookie.match(reg); if (array) { return unescape(array[2]); } else { return ""; } } // 检查Cookie是否存在 function checkMarTech2Cookie(key) { var value = getMarTech2Cookie(key); if (value != "") { return true; } else { return false; } } // 删除指定Cookie function deleteMarTech2Cookie(key) { // 将Cookie的有效期设置为过去时间 var d = new Date(); d.setTime(d.getTime() - (30 * 24 * 3600 * 1000)); var expires = "expires=" + d.toGMTString(); // 设置Cookie document.cookie = key + "=;" + expires + ";path=/"; } /* * JavaScript MD5 * https://github.com/blueimp/JavaScript-MD5 * * Copyright 2011, Sebastian Tschan * https://blueimp.net * * Licensed under the MIT license: * https://opensource.org/licenses/MIT * * Based on * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message * Digest Algorithm, as defined in RFC 1321. * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet * Distributed under the BSD License * See http://pajhome.org.uk/crypt/md5 for more info. */ /* global define */ /* eslint-disable strict */ ;(function($) { 'use strict' /** * Add integers, wrapping at 2^32. * This uses 16-bit operations internally to work around bugs in interpreters. * * @param {number} x First integer * @param {number} y Second integer * @returns {number} Sum */ function safeAdd(x, y) { var lsw = (x & 0xffff) + (y & 0xffff) var msw = (x >> 16) + (y >> 16) + (lsw >> 16) return (msw << 16) | (lsw & 0xffff) } /** * Bitwise rotate a 32-bit number to the left. * * @param {number} num 32-bit number * @param {number} cnt Rotation count * @returns {number} Rotated number */ function bitRotateLeft(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)) } /** * Basic operation the algorithm uses. * * @param {number} q q * @param {number} a a * @param {number} b b * @param {number} x x * @param {number} s s * @param {number} t t * @returns {number} Result */ function md5cmn(q, a, b, x, s, t) { return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b) } /** * Basic operation the algorithm uses. * * @param {number} a a * @param {number} b b * @param {number} c c * @param {number} d d * @param {number} x x * @param {number} s s * @param {number} t t * @returns {number} Result */ function md5ff(a, b, c, d, x, s, t) { return md5cmn((b & c) | (~b & d), a, b, x, s, t) } /** * Basic operation the algorithm uses. * * @param {number} a a * @param {number} b b * @param {number} c c * @param {number} d d * @param {number} x x * @param {number} s s * @param {number} t t * @returns {number} Result */ function md5gg(a, b, c, d, x, s, t) { return md5cmn((b & d) | (c & ~d), a, b, x, s, t) } /** * Basic operation the algorithm uses. * * @param {number} a a * @param {number} b b * @param {number} c c * @param {number} d d * @param {number} x x * @param {number} s s * @param {number} t t * @returns {number} Result */ function md5hh(a, b, c, d, x, s, t) { return md5cmn(b ^ c ^ d, a, b, x, s, t) } /** * Basic operation the algorithm uses. * * @param {number} a a * @param {number} b b * @param {number} c c * @param {number} d d * @param {number} x x * @param {number} s s * @param {number} t t * @returns {number} Result */ function md5ii(a, b, c, d, x, s, t) { return md5cmn(c ^ (b | ~d), a, b, x, s, t) } /** * Calculate the MD5 of an array of little-endian words, and a bit length. * * @param {Array} x Array of little-endian words * @param {number} len Bit length * @returns {Array} MD5 Array */ function binlMD5(x, len) { /* append padding */ x[len >> 5] |= 0x80 << len % 32 x[(((len + 64) >>> 9) << 4) + 14] = len var i var olda var oldb var oldc var oldd var a = 1732584193 var b = -271733879 var c = -1732584194 var d = 271733878 for (i = 0; i < x.length; i += 16) { olda = a oldb = b oldc = c oldd = d a = md5ff(a, b, c, d, x[i], 7, -680876936) d = md5ff(d, a, b, c, x[i + 1], 12, -389564586) c = md5ff(c, d, a, b, x[i + 2], 17, 606105819) b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330) a = md5ff(a, b, c, d, x[i + 4], 7, -176418897) d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426) c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341) b = md5ff(b, c, d, a, x[i + 7], 22, -45705983) a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416) d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417) c = md5ff(c, d, a, b, x[i + 10], 17, -42063) b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162) a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682) d = md5ff(d, a, b, c, x[i + 13], 12, -40341101) c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290) b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329) a = md5gg(a, b, c, d, x[i + 1], 5, -165796510) d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632) c = md5gg(c, d, a, b, x[i + 11], 14, 643717713) b = md5gg(b, c, d, a, x[i], 20, -373897302) a = md5gg(a, b, c, d, x[i + 5], 5, -701558691) d = md5gg(d, a, b, c, x[i + 10], 9, 38016083) c = md5gg(c, d, a, b, x[i + 15], 14, -660478335) b = md5gg(b, c, d, a, x[i + 4], 20, -405537848) a = md5gg(a, b, c, d, x[i + 9], 5, 568446438) d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690) c = md5gg(c, d, a, b, x[i + 3], 14, -187363961) b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501) a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467) d = md5gg(d, a, b, c, x[i + 2], 9, -51403784) c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473) b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734) a = md5hh(a, b, c, d, x[i + 5], 4, -378558) d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463) c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562) b = md5hh(b, c, d, a, x[i + 14], 23, -35309556) a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060) d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353) c = md5hh(c, d, a, b, x[i + 7], 16, -155497632) b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640) a = md5hh(a, b, c, d, x[i + 13], 4, 681279174) d = md5hh(d, a, b, c, x[i], 11, -358537222) c = md5hh(c, d, a, b, x[i + 3], 16, -722521979) b = md5hh(b, c, d, a, x[i + 6], 23, 76029189) a = md5hh(a, b, c, d, x[i + 9], 4, -640364487) d = md5hh(d, a, b, c, x[i + 12], 11, -421815835) c = md5hh(c, d, a, b, x[i + 15], 16, 530742520) b = md5hh(b, c, d, a, x[i + 2], 23, -995338651) a = md5ii(a, b, c, d, x[i], 6, -198630844) d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415) c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905) b = md5ii(b, c, d, a, x[i + 5], 21, -57434055) a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571) d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606) c = md5ii(c, d, a, b, x[i + 10], 15, -1051523) b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799) a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359) d = md5ii(d, a, b, c, x[i + 15], 10, -30611744) c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380) b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649) a = md5ii(a, b, c, d, x[i + 4], 6, -145523070) d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379) c = md5ii(c, d, a, b, x[i + 2], 15, 718787259) b = md5ii(b, c, d, a, x[i + 9], 21, -343485551) a = safeAdd(a, olda) b = safeAdd(b, oldb) c = safeAdd(c, oldc) d = safeAdd(d, oldd) } return [a, b, c, d] } /** * Convert an array of little-endian words to a string * * @param {Array} input MD5 Array * @returns {string} MD5 string */ function binl2rstr(input) { var i var output = '' var length32 = input.length * 32 for (i = 0; i < length32; i += 8) { output += String.fromCharCode((input[i >> 5] >>> i % 32) & 0xff) } return output } /** * Convert a raw string to an array of little-endian words * Characters >255 have their high-byte silently ignored. * * @param {string} input Raw input string * @returns {Array} Array of little-endian words */ function rstr2binl(input) { var i var output = [] output[(input.length >> 2) - 1] = undefined for (i = 0; i < output.length; i += 1) { output[i] = 0 } var length8 = input.length * 8 for (i = 0; i < length8; i += 8) { output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << i % 32 } return output } /** * Calculate the MD5 of a raw string * * @param {string} s Input string * @returns {string} Raw MD5 string */ function rstrMD5(s) { return binl2rstr(binlMD5(rstr2binl(s), s.length * 8)) } /** * Calculates the HMAC-MD5 of a key and some data (raw strings) * * @param {string} key HMAC key * @param {string} data Raw input string * @returns {string} Raw MD5 string */ function rstrHMACMD5(key, data) { var i var bkey = rstr2binl(key) var ipad = [] var opad = [] var hash ipad[15] = opad[15] = undefined if (bkey.length > 16) { bkey = binlMD5(bkey, key.length * 8) } for (i = 0; i < 16; i += 1) { ipad[i] = bkey[i] ^ 0x36363636 opad[i] = bkey[i] ^ 0x5c5c5c5c } hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8) return binl2rstr(binlMD5(opad.concat(hash), 512 + 128)) } /** * Convert a raw string to a hex string * * @param {string} input Raw input string * @returns {string} Hex encoded string */ function rstr2hex(input) { var hexTab = '0123456789abcdef' var output = '' var x var i for (i = 0; i < input.length; i += 1) { x = input.charCodeAt(i) output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f) } return output } /** * Encode a string as UTF-8 * * @param {string} input Input string * @returns {string} UTF8 string */ function str2rstrUTF8(input) { return unescape(encodeURIComponent(input)) } /** * Encodes input string as raw MD5 string * * @param {string} s Input string * @returns {string} Raw MD5 string */ function rawMD5(s) { return rstrMD5(str2rstrUTF8(s)) } /** * Encodes input string as Hex encoded string * * @param {string} s Input string * @returns {string} Hex encoded string */ function hexMD5(s) { return rstr2hex(rawMD5(s)) } /** * Calculates the raw HMAC-MD5 for the given key and data * * @param {string} k HMAC key * @param {string} d Input string * @returns {string} Raw MD5 string */ function rawHMACMD5(k, d) { return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d)) } /** * Calculates the Hex encoded HMAC-MD5 for the given key and data * * @param {string} k HMAC key * @param {string} d Input string * @returns {string} Raw MD5 string */ function hexHMACMD5(k, d) { return rstr2hex(rawHMACMD5(k, d)) } /** * Calculates MD5 value for a given string. * If a key is provided, calculates the HMAC-MD5 value. * Returns a Hex encoded string unless the raw argument is given. * * @param {string} string Input string * @param {string} [key] HMAC key * @param {boolean} [raw] Raw output switch * @returns {string} MD5 output */ function md5(string, key, raw) { if (!key) { if (!raw) { return hexMD5(string) } return rawMD5(string) } if (!raw) { return hexHMACMD5(key, string) } return rawHMACMD5(key, string) } if (typeof define === 'function' && define.amd) { define(function() { return md5 }) } else if (typeof module === 'object' && module.exports) { module.exports = md5 } else { $.md5 = md5 } })(this)