探针项目代码总结
探针项目代码总结:
工作:
1.增加局部和全局属性和各自增删改查(局部属性中多出两个方法1.设置 _business_id 2 .设置 _instance_id)
2.增加自定义事件上报
1公共部分
1.1在常量集合里面增加全局属性字段和各字段长度和属性个数限制
export const CONST_KEY = {NLAPM_LOGIN_NAME_GLOBAL: "NLAPM_LOGIN_NAME_GLOBAL",NLAPM_GLOBAL_PROPERTIES: "globalProperties",MAX_KEY_LENGTH: 32,MAX_VALUE_LENGTH : 128,MAX_PAGE_PROPERTIES_NUM: 5,MAX_GLOBAL_PROPERTIES_NUM: 3,MAX_TRACK_PROPERTIES_NUM: 20,
}
1.2增加check函数
对传入参数是否合法进行判断
判断逻辑顺序:
1.不能为空
2.不能为嵌套对象,即对象中key-value的value不能再为对象
3.键的长度不能超过限制(32)
4.值的长度不能超过限制(128)
PS.因为后续考虑到属性个数不能超过限制这一判断逻辑不能做到统一:初始化的时候可以就参数判断个数不能超过限制,但是追加的时候得和对象中原有的key进行汇总并去重计数来判断属性不能超过限制,所以就没有写在统一的check 函数中进行判断。故check函数就单纯只是对传入参数的合法性进行判断而已,至于属性个数由于逻辑差别较大,在需要判断的时候在各自函数里面写
export function check(obj){if(!obj) {return false;}const keys = Object.keys(obj);for (const key of keys) {const value = obj[key];if (typeof value === "object") {return false;}}Object.keys(obj).forEach(key => {if (key.length > CONST_KEY.MAX_KEY_LENGTH) {return false;}const valueLength = obj[key].toString().length;if (valueLength > CONST_KEY.MAX_VALUE_LENGTH) {return false;}})return true;}
1.3访问限制
为安全性,则将可被外部调用的方法统一放在外面,而baseinfo
等内部信息放在不允许直接用windows.
来引用
window.nlapmPlugin = EXPlugin;
const EXPlugin = {login : NLAPMPlugin.login ,......};
2局部属性
2.1总体思路
在baseinfo
中增加pageProperties
对象,1初始化2追加3全删4按字段删5获取全部 ,这五个需求都按照javascript
中对对象的增删改查来实现
2.2初始化
代码逻辑顺序:
1.调用check函数判断参数的合法性
2.判断属性个数是否超出限制
3.清空pageProperties对象并重新赋值
setPageProfile(properties) {if(!check(properties))return false;const numOfKeys = Object.keys(properties).length;if(numOfKeys>CONST_KEY.MAX_PAGE_PROPERTIES_NUM) {return false;}NLAPMPlugin.baseInfo.pageProperties = {};NLAPMPlugin.baseInfo.pageProperties = properties;return true;},
2.3追加
2.3.1思路
由于追加之后还需要判断是否超出属性个数限制,而传入的key可能重复,则需要用map或者set判重,考虑到map性能和set差不多,还有直接用map的话思路更加简单直接,所以采用map
2.3.2代码逻辑顺序
1.调用check函数判断参数的合法性
2.创建临时变量,追加传入参数
3.判断是否超出属性个数限制
3.1超出则return false;
3.2没超出则赋值回真正的baseinfo
里面的pageProperties
里面
2.3.3代码
appendPageProfile(properties) {if(!check(properties))return false;let tobj = {...NLAPMPlugin.baseInfo.pageProperties,...properties};if(Object.keys(tobj).length>CONST_KEY.MAX_PAGE_PROPERTIES_NUM) return false;NLAPMPlugin.baseInfo.pageProperties = {...tobj};return true;},
2.4全删
直接把pageProperties对象置空即可
deletePageProfile(){NLAPMPlugin.baseInfo.pageProperties = {};return true;},
2.5按字段删
2.5.1思路
由于按字段删需要传入的属性类型为string或者string数组,则代码中进行判断,若传入参数为string数组,则遍历数组执行删除,若为单一字符串,则对此单一字符串删除。
由于javascript中自带的delete方法在原本没有该属性的时候只会简单return false 不会报错。所以是安全的。
2.5.2代码
unsetPageProfile(properties){if(!check(properties))return false;if (Array.isArray(properties)) {properties.forEach(function(property) {let tmp = propertydelete NLAPMPlugin.baseInfo.pageProperties[tmp];});} else {let tmp = propertiesdelete NLAPMPlugin.baseInfo.pageProperties[tmp];}return true;},
2.6获取全部
2.6.1思路
获取全部需要注意的点为不能直接把baseinfo
里面的pageProperties
传入(这样有可能会被外面改),则让传出的是一个赋值后的对象即可,使用javascript
中的展开操作符(Spread operator)
【… 】来赋值,而展开操作符对非嵌套对象是深拷贝,故可用(因为所有增加对象中属性的方法都要check函数来限制参数为非嵌套对象)。
2.6.2 代码
getPageProfile(){if(!NLAPMPlugin.baseInfo.pageProperties)return;let tmp = { ...NLAPMPlugin.baseInfo.pageProperties } ;return tmp;},
2.7在local中增加两个方法
2.7.1设置 _business_id
由于此属性受到和局部属性pageProperties
里面属性一样的限制。故逻辑判断,若原本无此_business_id
字段,而对象中原本属性个数已经到了最大属性个数,则会超出,此时return false;
即可
setBusinessId(property) {if(!property){return false;}if(property.length>CONST_KEY.MAX_VALUE_LENGTH) return false;if(!NLAPMPlugin.baseInfo.pageProperties._business_id && Object.keys(NLAPMPlugin.baseInfo.pageProperties).length>4){return false;}NLAPMPlugin.baseInfo.pageProperties._business_id = property;return true;},
2.7.2设置 _instance_id
思路同上
setBusinessInstanceId(property) {if(!property){return false;}if(property.length>CONST_KEY.MAX_VALUE_LENGTH) return false;if(!NLAPMPlugin.baseInfo.pageProperties._instance_id && Object.keys(NLAPMPlugin.baseInfo.pageProperties).length>4){return false;}NLAPMPlugin.baseInfo.pageProperties._instance_id = property;return true;},},
3全局属性
3.1总体思路
由于需要实现在不同页面中访问时,全局属性保持同步。故采用localstorage
来存储。每次更改和获取都调用localstorage
的set和get方法来获取和设置localstorage
对象。只需要在最后的上报逻辑之中加上globalProperties
属性即可实现每次都能上报此全局属性。
至于增删改查逻辑思路和局部属性相同,后续报告中只罗列代码,思路同局部属性。
let reportData = option.data.map(map => {map[CONST_KEY.NLAPM_GLOBAL_PROPERTIES] = JSON.parse(localStorage.getItem(CONST_KEY.NLAPM_GLOBAL_PROPERTIES));return {headers: {licenseKey: NLAPMPlugin.baseInfo.licenseKey,type: `web_${option.type}`,},body: JSON.stringify(map)}}
3.2初始化
setProfile(properties) {if(!check(properties))return false;const numOfKeys = Object.keys(properties).length;if(numOfKeys>CONST_KEY.MAX_GLOBAL_PROPERTIES_NUM) return false;localStorage.setItem(CONST_KEY.NLAPM_GLOBAL_PROPERTIES, JSON.stringify(properties));return true;},
3.3追加
appendProfile(properties) {if(!check(properties))return false;let globalPropsJSON = localStorage.getItem(CONST_KEY.NLAPM_GLOBAL_PROPERTIES);let parsedObj = globalPropsJSON ? JSON.parse(globalPropsJSON) : {};let tobj = {...parsedObj,...properties};if(Object.keys(tobj).length>CONST_KEY.MAX_GLOBAL_PROPERTIES_NUM)return false;localStorage.setItem(CONST_KEY.NLAPM_GLOBAL_PROPERTIES, JSON.stringify(tobj));return true;},
3.4全删
deleteProfile(){let parsedObj = {};localStorage.setItem(CONST_KEY.NLAPM_GLOBAL_PROPERTIES, JSON.stringify(parsedObj));return true;},
3.5按字段删
unsetProfile(properties){if(!check(properties))return false;let globalPropsJSON = localStorage.getItem(CONST_KEY.NLAPM_GLOBAL_PROPERTIES);let parsedObj = globalPropsJSON ? JSON.parse(globalPropsJSON) : {};if (Array.isArray(properties)) {properties.forEach(function(property) {let tmp = property;delete parsedObj[tmp];});} else {let tmp = propertiesdelete parsedObj[tmp];}localStorage.setItem(CONST_KEY.NLAPM_GLOBAL_PROPERTIES, JSON.stringify(parsedObj));return true;},
3.6获取全部
getProfile(){let globalPropsJSON = localStorage.getItem(CONST_KEY.NLAPM_GLOBAL_PROPERTIES);if(!globalPropsJSON)return;let parsedObj = JSON.parse(globalPropsJSON);let tmp = { ...parsedObj};return tmp;},
4自定义事件
4.1思路
track(trackName,trackProperties)
在click.js
同级创建一个新文件track.js
在判定好两个参数trackName
和trackProperties
的合法性之后直接赋值即可
其中:
extendId
字段使用guid()
获取的没有-的uuid
time
字段使用(new Date()).getTime()
获取当前时间戳
4.2代码
function track(eventName ='',properties = {}){if(eventName.length>CONST_KEY.MAX_VALUE_LENGTH) return false;if(!check(properties)) return false;const numOfKeys = Object.keys(properties).length;if(numOfKeys>CONST_KEY.MAX_TRACK_PROPERTIES_NUM) {return false;}if (NLAPMPlugin.control.agentSwitch) {try {report({type: "extend",data: {...NLAPMPlugin.baseInfo,trackName:eventName,trackProperties :properties,event : 'WebExtend',time: (new Date()).getTime(),extendId: guid(),}});} catch (e) {}}return true;
}