1 检测服务器所支持的请求方法。(比如:‘/user’路由支持哪些方法:get、post、delete…)
2 CORS中的预检请求(检测某个接口是否支持跨域),客户端使用XmlHttpRequest发起Ajax请求,当前绝大部分浏览器已经支持CORS方式,且主流浏览器均提供了对跨域资源共享的支持。
前端异常包含很多种情况:1. js编译时异常(开发阶段就能排除)2. js运行时异常;3. 加载静态资源异常(路径写错、资源服务器异常、CDN异常、跨域)4. 接口请求异常等
监控流程:监控错误 -> 搜集错误 -> 存储错误 -> 分析错误 -> 错误报警-> 定位错误 -> 解决错误
// 设置日志对象类的通用属性
function setCommonProperty() {
this.happenTime = new Date().getTime(); // 日志发生时间
this.webMonitorId = WEB_MONITOR_ID; // 用于区分应用的唯一标识(一个项目对应一个)
this.simpleUrl = window.location.href.split('?')[0].replace('#', ''); // 页面的url
this.customerKey = utils.getCustomerKey(); // 用于区分用户,所对应唯一的标识,清理本地数据后失效
this.pageKey = utils.getPageKey(); // 用于区分页面,所对应唯一的标识,每个新页面对应一个值
this.deviceName = DEVICE_INFO.deviceName;
this.os = DEVICE_INFO.os + (DEVICE_INFO.osVersion ? " " + DEVICE_INFO.osVersion : "");
this.browserName = DEVICE_INFO.browserName;
this.browserVersion = DEVICE_INFO.browserVersion;
// TODO 位置信息, 待处理
this.monitorIp = ""; // 用户的IP地址
this.country = "china"; // 用户所在国家
this.province = ""; // 用户所在省份
this.city = ""; // 用户所在城市
// 用户自定义信息, 由开发者主动传入, 便于对线上进行准确定位
this.userId = USER_INFO.userId;
this.firstUserParam = USER_INFO.firstUserParam;
this.secondUserParam = USER_INFO.secondUserParam;
}
// JS错误日志,继承于日志基类MonitorBaseInfo
function JavaScriptErrorInfo(uploadType, errorMsg, errorStack) {
setCommonProperty.apply(this);
this.uploadType = uploadType;
this.errorMessage = encodeURIComponent(errorMsg);
this.errorStack = errorStack;
this.browserInfo = BROWSER_INFO;
}
JavaScriptErrorInfo.prototype = new MonitorBaseInfo();
封装了一个Js错误对象JavaScriptErrorInfo,用以保存页面中产生的Js错误。其中,setCommonProperty用以设置所有日志对象的通用属性。
1)重写window.onerror 方法, 大家熟知,监控JS错误必然离不开它,有人对他进行了测试测试介绍感觉也是比较用心了
2)重写console.error方法,为什么要重写这个方法,我不能够给出明确的答案,如果App首次向浏览器注入的Js代码报错了,window.onerror是无法监控到的,所以只能重写console.error的方式来进行捕获,也许会有更好的办法。待window.onerror成功后,此方法便不再需要用了
3)重写window.onunhandledrejection方法。 当你用到Promise的时候,而你又忘记写reject的捕获方法的时候,系统总是会抛出一个叫 Unhandled Promise rejection. 没有堆栈,没有其他信息,特别是在写fetch请求的时候很容易发生。 所以我们需要重写这个方法,以帮助我们监控此类错误
下边是启动JS错误监控代码:
一、重写window.onerror 方法:
// 重写 onerror 进行jsError的监听
window.onerror = function(errorMsg, url, lineNumber, columnNumber, errorObj) {
jsMonitorStarted = true;
var errorStack = errorObj ? errorObj.stack : null;
siftAndMakeUpMessage(errorMsg, url, lineNumber, columnNumber, errorStack);
};
二、重写console.error方法:
var oldError = console.error;
console.error = function (errorMsg) {
siftAndMakeUpMessage(errorMsg, WEB_LOCATION, 0, 0, {"CustomizeError": "CustomizeError: No error stack"});
return oldError.apply(console, arguments);
};
三、重写window.onunhandledrejection方法:
window.onunhandledrejection = function(e) {
var errorMsg = "";
if (typeof e.reason === "object") {
errorMsg = JSON.stringify(e.reason);
} else {
errorMsg = e.reason;
}
siftAndMakeUpMessage(errorMsg, WEB_LOCATION, 0, 0, {"CustomizeError": "CustomizeError: No error stack"});
}
OK, 错误日志有了,该怎么计算错误率呢?
JS错误发生率 = JS错误个数(一次访问页面中,所有的js错误都算一次)/PV (PC,IOS,Android平台同理)
所以我们需要记下页面的PV记录
/**
* 添加一个定时器,进行数据的上传
* 2秒钟进行一次URL是否变化的检测
* 10秒钟进行一次数据的检查并上传
*/
var timeCount = 0;
setInterval(function () {
checkUrlChange();
// 循环5后次进行一次上传
if (timeCount >= 25) {
// 如果是本地的localhost, 就忽略,不进行上传
var logInfo = (localStorage[ELE_BEHAVIOR] || "") +
(localStorage[JS_ERROR] || "") +
(localStorage[HTTP_LOG] || "") +
(localStorage[SCREEN_SHOT] || "") +
(localStorage[CUSTOMER_PV] || "") +
(localStorage[LOAD_PAGE] || "") +
(localStorage[RESOURCE_LOAD] || "");
if (logInfo) {
localStorage[ELE_BEHAVIOR] = "";
localStorage[JS_ERROR] = "";
localStorage[HTTP_LOG] = "";
localStorage[SCREEN_SHOT] = "";
localStorage[CUSTOMER_PV] = "";
localStorage[LOAD_PAGE] = "";
localStorage[RESOURCE_LOAD] = "";
utils.ajax("POST", HTTP_UPLOAD_LOG_INFO, {logInfo: logInfo}, function (res) {}, function () {})
}
timeCount = 0;
}
timeCount ++;
}, 200);
上边的代码我用了定时器,大概的意思是200毫秒进行一次URL变化的检查,5秒进行一次数据的检查,如果有数据就进行上传,并清空上一次的数据。为什么用定时器呢,因为在单页应用中,路由的切换和地址栏的变化是无法被监控的,我确实没有想到特别好的办法来监控,所以用了这种方式,如果有人有更好的办法,请给我留言,谢谢。
封装简易的Ajax
为了将这些数据上传到我们的服务器,我们总不能每次都用xmlHttpRequest来发送ajax请求吧,所以我们需要自己封装一个简单的Ajax
/**
*
* @param method 请求类型(大写) GET/POST
* @param url 请求URL
* @param param 请求参数
* @param successCallback 成功回调方法
* @param failCallback 失败回调方法
*/
this.ajax = function(method, url, param, successCallback, failCallback) {
var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
xmlHttp.open(method, url, true);
xmlHttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
var res = JSON.parse(xmlHttp.responseText);
typeof successCallback == 'function' && successCallback(res);
} else {
typeof failCallback == 'function' && failCallback();
}
};
xmlHttp.send("data=" + JSON.stringify(param));
}
HTML:table去边框方法
给table、th、td元素添加border: 0;样式
给table、th、td元素添加border-style: none;样式
给table、th、td元素添加border: transparent;样式
使用字符 代替空格;
设置style样式 white-space:pre,浏览器会保留文本中的空格和换行;
使用标签 ,被包围在 标签 元素中的文本通常会保留空格和换行符。
VUE:项目使用过npm run build – report吗?
vue-cli3下的typescript项目,在build时想要生成分析报告进行性能优化。不生成报告原因
HTML:元素设置浮动,特征是什么?在HTML中,浮动就是让元素可以向左或向右移动,直到它的外边距碰到其父级的内边距或者是上一个元素的外边距,只需要给元素设置“float:left|right|none|inherit”样式即可。
浮动的特性
1.支持所有的css样式
2.内容撑开宽高
3.多个元素设置浮动,会排在一排
4.脱离文档流
5.提升层级半级
也就是说:一个元素设置了浮动属性后,下一个元素就会无视这个元素的存在,但是下一个元素中的文本内容依然会为这个元素让出位置使自身的文本内容环绕在设置浮动元素的周围
注意:不管是什么属性的元素,如果设置了浮动属性,该元素就变成了具有inline-block属性的元素。
1)没有设置浮动的元素会填充浮动元素留下来的空间
2)浮动元素会和非浮动元素发生重叠,浮动元素会在图层的最上面
3)使用浮动时,该元素会脱离文档流,后面的元素会无视这个元素,但依然会为这个浮动元素让出位置,并且元素中的文字内容会环绕在其周围。
浮动元素不会在其浮动方向上溢出父级的包含块
也就是说元素左浮动,其左外边距不会超过父级的左内边距,元素右浮动,其右外边距不会超过父级的右内边距
2)浮动元素的位置受到同级同向浮动元素的影响
也就是说同一父级中有多个浮动元素,后一个元素的位置会受到前一个浮动元素位置的影响,他们不会相互遮挡,后一个浮动元素会紧挨着前一个浮动元素的左外边距进行定位,如果当前空间不足,则会换行,否则会放置在前一个浮动元素的下面。
小程序:mp协议MP协议的全称是Measurement Protocol(测量协议),测量协议是一套规则,是Google Analytics跨设备跟踪的解决方案,适用于邮件跟踪,微信小程序,电商后台数据传送等场景。
通过该协议您可以收集和跟踪用户的原始互动数据并通过 HTTP 请求直接发送到 Google Analytics(分析)服务器。通过Google Analytics强大的分析功能分析用户行为数据,为您提供直观的数据报告,帮助您降低运营成本,实现精准营销。
Measurement Protocol使用流程:
1.提取您需要的数据。
2.将所需要的数据按照测量协议的格式组装。
3.发送组装好的请求给Google Analytics(分析)服务器。
4.如果Google Analytics(分析)服务器成功处理传输数据,服务器将会返回状态200。
VUE:举例说明什么是动态prop?prop的作用是父组件向子组件单向传递数据,这个过程是单向的。传递的属性可以是静态的,可以是动态的,可以是数字,可以是字符串,可以是数组,还可以是对象,甚至可以在传递数据的时候写一个校验函数进行校验。
例子
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)