UNPKG

@aligov/retcodelog

Version:

retcode log上报npm包,适用于 browser|nodejs|weex|E应用

492 lines (427 loc) 12.9 kB
module.exports = function (wpo, root, conf) { var cookies = {}; var count = 0; var uid, timer; var config = { // 默认上报上报 imgUrl : '//retcode.taobao.com/r.png?', // 默认抽样率 sample : 10, modVal : 1, // 是否开启动态配置功能 dynamic: false, // API抽样率 retCode: {}, delayOfReady: null }; /** * safety function caller * @param {Function} fn * @param {Array} args * @param {*} defaultValue * @return {*} */ var safetyCall = function (fn, args, defaultValue) { if (typeof fn !== 'function') return defaultValue; try { return fn.apply(this, args); } catch (ex) { return defaultValue; } } var sendRequest = conf.sendRequest; var _send = function () { var params, obj; // 发送log.js异步加载前的数据队列 if (wpo.asyncQueue && wpo.asyncQueue.length > 0) { var asyncQueue = wpo.asyncQueue; var item; while (item = asyncQueue.shift()) { var method = item.method; if (typeof wpo[method] === 'function') { wpo[method].apply(wpo, item.args || []); } } } while (params = core.dequeue()) { obj = core.extend({ uid : uid, userNick: wpo.getNick(), times : params.times ? params.times : 1, _t : ~new Date() + (count++).toString(), tag : wpo.config.tag && safetyCall(wpo.config.tag, [], wpo.config.tag + '') || '' }, params); // 最后一次尝试补齐spm值 if (!obj.spm) { obj.spm = wpo.getSpmId(); } if (!obj.spm) { break; } if (wpo.debug && typeof window === 'object' && window.console) { console.log(obj); } sendRequest.call(wpo, config.imgUrl + core.query.stringify(obj)); } timer = null; }; /** * 延时发送 * * @param _clear 是否立即发送 * @param delay 延时多久发送 * @private */ var _wait = function (_clear) { if (_clear && timer) { clearTimeout(timer); _send(); } if (!timer) { timer = setTimeout(_send, 1000); } }; var core = { _key: 'wpokey', // 版本号 ver: '<%= pkg.version %>', // dynamically updates itself without queue requestQueue: wpo.requestQueue || [], /** * 获取cookie * * @param name * @returns {*} */ getCookie: function (name) { var reg, matches, cookie = ''; if (!cookies[name]) { reg = new RegExp(name + '=([^;]+)'); // // to make it compatible with nodejs // try { cookie = conf.getCookie(this); } catch (e) { } matches = reg.exec(cookie); if (matches) { cookies[name] = matches[1]; } } return cookies[name]; }, /** * 设置cookie * * @param key * @param value * @param expires * @param domain * @param path */ setCookie: function (key, value, expires, domain, path) { var str = key + '=' + value; if (domain) { str += ('; domain=' + domain); } if (path) { str += ('; path=' + path); } if (expires) { str += ('; expires=' + expires); } document.cookie = str; }, /** * 扩展对象 * * @param target * @returns {*} */ extend: function (target) { var args = Array.prototype.slice.call(arguments, 1); for (var i = 0, len = args.length, arg; i < len; i++) { arg = args[i]; for (var name in arg) { if (arg.hasOwnProperty(name)) { target[name] = arg[name]; } } } return target; }, /** * 获取guid * * @returns {string} */ guid: function () { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); }, /** * 发送请求 * * @param params */ send: function (params) { // 如果没有禁用wpo则上报, e.g., daily环境可禁用wpo上报,防止数据污染 if (params && !wpo.config.disabled) { var spm = core.getSpmId(); // 如果尚未设置过spm,并且成功获取到spm,则锁定spm值 // 加入队列的时候即固定了此次上报的spm,方便SPA应用通过setConfig动态修改spm if (!params.spm && spm) { params.spm = spm; } this.queue(params); } }, query: { /** * 对象转url字符串 * * @param params * @returns {string} */ stringify: function (params) { var arr = []; var str = ''; // encodeURIComponent异常保护 try { for (var name in params) { if (params.hasOwnProperty(name) && params[name] !== undefined) { var encodeInfo = ''; if(name == 'spm'){ encodeInfo = encodeURI(params[name]); } else { encodeInfo = encodeURIComponent(params[name]); } arr.push(name + '=' + encodeInfo); } } if (arr.length > 0) { str = arr.join('&'); } } catch (e) { } return str; }, /** * url字符串转对象 * * @param str * @returns {{}} */ parse: function (str) { var pairs = str.split('&'), obj = {}, pair; // decodeURIComponent异常保护 try { for (var i = 0, len = pairs.length; i < len; i++) { pair = pairs[i].split('='); obj[pair[0]] = decodeURIComponent(pair[1]); } } catch (e) { } return obj; } }, /** * 获取spmId * * @returns {*} */ getSpmId: function () { if (config.spmId) { return config.spmId; } else if (typeof conf.getSpmId === 'function') { return conf.getSpmId.call(this); } return 0; }, /** * 事件绑定 * * @param el * @param type * @param func * @param isRemoving */ on: function (el, type, func, isRemoving) { if (el.addEventListener) { el.addEventListener(type, isRemoving ? function () { el.removeEventListener(type, func, false); func(); } : func, false); } else if (el.attachEvent) { el.attachEvent('on' + type, function () { if (isRemoving) { el.detachEvent('on' + type, arguments.callee); } func(); }); } }, /** * 获取用户的taobao nick * * @returns {*} */ getNick: function () { var nick = ''; try { // 优先取业务方主动配置的nick if (wpo.config.nick) { nick = wpo.config.nick; } // 否则从cookie中读取 else { // 分别取淘宝PC,淘宝无线,商家子账号cookie nick = this.getCookie('_nk_') || this.getCookie('lgc') || this.getCookie('_w_tb_nick') || this.getCookie('sn') || ''; nick = decodeURIComponent(nick); } } catch (e) { } return nick; }, /** * 设置config * @param inConfig * @returns {*} */ setConfig: function (conf) { if (conf && typeof conf !== 'object') { throw 'args of wpo.setConfig is not object'; return; } // weex环境 if (conf && conf.user && typeof conf.user.getUserInfo === 'function' && this.env === 'weex') { // 设置nick conf.user.getUserInfo(function (res) { try { res = JSON.parse(res); } catch (e) { } core.extend(config, { nick: res.info && res.info.nick }); }); } return core.extend(config, conf); }, /** * 快捷配置spm,返回wpo自身方便链式调用 * * @param spm * @returns {core} */ spm: function (spm) { if (spm) { this.setConfig({ spmId: spm }) } return this; }, /** * 动态配置 * * @param obj */ dynamicConfig: function (obj) { var config = this.query.stringify(obj); try { localStorage.setItem(this._key, config); } catch (e) { this.setCookie(this._key, config, new Date(obj.expTime)); } this.setConfig({ sample: parseInt(obj.sample, 10) }); this.ready(); }, /** * ready * */ ready: function () { var _ready = function () { wpo._ready = true; _wait(); }; if (wpo.config.delayOfReady) { setTimeout(function () { _ready(); }, wpo.config.delayOfReady) } else { _ready(); } }, /** * 加入请求队列 * * @param obj */ queue: function (obj) { var queue = this.requestQueue, compare; if (obj.type === 'jserror') { if (queue.length) { compare = queue[queue.length - 1]; if (obj.msg === compare.msg) { compare.times++; return; } } if (!obj.times) { obj.times = 1; } } queue.push(obj); if (this._ready) { if (obj.type === 'jserror') { // js error延时1s发送,方便合并大量同类错误 _wait(false, 1000); } else { _send(); } } }, /** * 从请求队列取头部取一个(第一个) * * @returns {T} */ dequeue: function () { return this.requestQueue.shift(); }, /** * clear */ clear: function () { _wait(true); } }; core.uid = (uid = core.guid()); core.config = core.setConfig(wpo.config); core.safetyCall = safetyCall; core.extend(wpo, core); root.__WPO = wpo; return wpo; };