spy-client 2.1.1-alpha.4 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/base.css +224 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/basicSpec.ts.html +740 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/block-navigation.js +79 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/checkSpec.ts.html +479 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/favicon.png +0 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/headSpec.ts.html +695 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/index.html +171 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/markSpec.ts.html +284 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/metricSpec.ts.html +977 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/prettify.css +1 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/prettify.js +2 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/sort-arrow-sprite.png +0 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/sorter.js +170 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/base.css +224 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/basicSpec.ts.html +740 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/block-navigation.js +79 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/checkSpec.ts.html +479 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/favicon.png +0 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/headSpec.ts.html +695 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/index.html +171 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/markSpec.ts.html +284 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/metricSpec.ts.html +977 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/prettify.css +1 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/prettify.js +2 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/sort-arrow-sprite.png +0 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/sorter.js +170 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/base.css +224 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/basicSpec.ts.html +740 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/block-navigation.js +79 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/checkSpec.ts.html +479 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/favicon.png +0 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/headSpec.ts.html +695 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/index.html +171 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/markSpec.ts.html +284 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/metricSpec.ts.html +977 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/prettify.css +1 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/prettify.js +2 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/sort-arrow-sprite.png +0 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/sorter.js +170 -0
- package/dist/head/base.d.ts +12 -7
- package/dist/lib/interface.d.ts +4 -0
- package/dist/spy-client-basic.d.ts +4 -1
- package/dist/spy-client-basic.esm.js +80 -21
- package/dist/spy-client-basic.iife.js +80 -21
- package/dist/spy-client-basic.iife.min.js +1 -1
- package/dist/spy-client-basic.js +80 -21
- package/dist/spy-client-basic.min.js +1 -1
- package/dist/spy-client-basic.mjs +80 -21
- package/dist/spy-client.d.ts +1 -0
- package/dist/spy-client.esm.js +107 -31
- package/dist/spy-client.iife.js +107 -31
- package/dist/spy-client.iife.min.js +1 -1
- package/dist/spy-client.js +107 -31
- package/dist/spy-client.min.js +1 -1
- package/dist/spy-client.mjs +107 -31
- package/dist/spy-head.js +46 -34
- package/dist/spy-head.min.js +1 -1
- package/dist/spy-local-cache.js +65 -65
- package/dist/spy-local-cache.min.js +1 -1
- package/example/local-cache.html +77 -15
- package/package.json +4 -12
- package/src/head/base.ts +37 -4
- package/src/head/error.ts +9 -19
- package/src/head/whitescreen.ts +14 -14
- package/src/lib/huffman.ts +37 -56
- package/src/lib/interface.ts +5 -0
- package/src/spy-client-basic.ts +92 -23
- package/src/spy-client.ts +19 -1
- package/src/spy-local-cache.ts +41 -16
package/dist/spy-client-basic.js
CHANGED
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
* @author kaivean
|
|
34
34
|
*/
|
|
35
35
|
var defaultLogServer = 'https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/mwb2.gif?';
|
|
36
|
-
var
|
|
36
|
+
var ver = navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?)_/);
|
|
37
|
+
var isLtIos14 = ver && ver[2] && (+ver[2] < 14);
|
|
37
38
|
function err(msg) {
|
|
38
39
|
console.error("[SpyClient_log]" + msg);
|
|
39
40
|
// throw new Error(msg);
|
|
@@ -50,6 +51,9 @@
|
|
|
50
51
|
return encodeURIComponent(key) + '=' + encodeURIComponent(value);
|
|
51
52
|
}).join('&');
|
|
52
53
|
}
|
|
54
|
+
function isArray(arr) {
|
|
55
|
+
return Object.prototype.toString.call(arr) === '[object Array]';
|
|
56
|
+
}
|
|
53
57
|
var SpyClient = /** @class */ (function () {
|
|
54
58
|
function SpyClient(option) {
|
|
55
59
|
this.sample = {};
|
|
@@ -62,38 +66,93 @@
|
|
|
62
66
|
lid: option.lid,
|
|
63
67
|
check: option.check !== false,
|
|
64
68
|
sample: option.sample,
|
|
69
|
+
localCache: option.localCache,
|
|
65
70
|
logServer: option.logServer || defaultLogServer,
|
|
66
71
|
};
|
|
67
72
|
}
|
|
68
|
-
SpyClient.prototype.
|
|
69
|
-
if (!
|
|
73
|
+
SpyClient.prototype.fetch = function (url, data) {
|
|
74
|
+
if (!window.fetch) {
|
|
70
75
|
return;
|
|
71
76
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
fetch(url, {
|
|
78
|
+
method: 'POST',
|
|
79
|
+
credentials: 'include',
|
|
80
|
+
headers: {
|
|
81
|
+
'Content-Type': 'application/json',
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify(data),
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
SpyClient.prototype.sendPost = function (data) {
|
|
87
|
+
var logItems = isArray(data) ? data : [data];
|
|
88
|
+
var first = logItems[0];
|
|
89
|
+
// 需要在页面暴漏出来pid等基本信息,方式调试查看基本信息与兼容目前的监控
|
|
90
|
+
var query = {
|
|
91
|
+
pid: first.pid,
|
|
92
|
+
type: first.type,
|
|
93
|
+
group: first.group,
|
|
94
|
+
};
|
|
95
|
+
var url = this.option.logServer + stringify(query);
|
|
96
|
+
if (!(!isLtIos14
|
|
97
|
+
&& navigator.sendBeacon
|
|
98
|
+
&& navigator.sendBeacon(url, JSON.stringify(data)))) {
|
|
99
|
+
this.fetch(url, data);
|
|
77
100
|
}
|
|
78
|
-
|
|
101
|
+
};
|
|
102
|
+
SpyClient.prototype.handle = function (logItem) {
|
|
103
|
+
if (!this.check(logItem)) {
|
|
79
104
|
return;
|
|
80
105
|
}
|
|
81
|
-
|
|
106
|
+
logItem = assign({
|
|
82
107
|
pid: this.option.pid,
|
|
83
108
|
lid: this.option.lid,
|
|
84
109
|
ts: Date.now(),
|
|
85
110
|
group: 'common',
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
111
|
+
}, logItem);
|
|
112
|
+
if (this.option.localCache) {
|
|
113
|
+
this.option.localCache.addLog(logItem);
|
|
114
|
+
}
|
|
115
|
+
// 当前api设置了抽样,
|
|
116
|
+
if (typeof logItem.sample === 'number') {
|
|
117
|
+
if (Math.random() > logItem.sample) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else if (typeof this.option.sample === 'number' && Math.random() > this.option.sample) { // 否则,用全局抽样
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
delete logItem.sample;
|
|
125
|
+
return logItem;
|
|
126
|
+
};
|
|
127
|
+
SpyClient.prototype.send = function (data, post) {
|
|
128
|
+
if (post === void 0) { post = false; }
|
|
129
|
+
var logItems = isArray(data) ? data : [data];
|
|
130
|
+
var postData = [];
|
|
131
|
+
for (var _i = 0, logItems_1 = logItems; _i < logItems_1.length; _i++) {
|
|
132
|
+
var logItem = logItems_1[_i];
|
|
133
|
+
logItem = this.handle(logItem);
|
|
134
|
+
if (!logItem) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
postData.push(logItem);
|
|
138
|
+
// 期望通过post方式上传日志
|
|
139
|
+
if (post) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
var url = this.option.logServer + stringify(logItem);
|
|
143
|
+
// 目前服务器端支持sendBeacon的post请求,可以优先采用,该api可以降低打点丢失率
|
|
144
|
+
// 但是ios有些问题:在webkit浏览内核环境下,beacon requests的请求方式存在证书验证的bug,发送失败但返回正确.
|
|
145
|
+
// 修复说明在如下链接中:https://bugs.webkit.org/show_bug.cgi?id=193508
|
|
146
|
+
// 但是目前为止,在iOS12.2版本中该问题依旧存在
|
|
147
|
+
// 2021-11-11: 发现ios 14可以送,故小于14的不发送
|
|
148
|
+
if (!(!isLtIos14
|
|
149
|
+
&& navigator.sendBeacon
|
|
150
|
+
&& navigator.sendBeacon(url))) {
|
|
151
|
+
(new Image()).src = url;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (post) {
|
|
155
|
+
this.sendPost(postData);
|
|
97
156
|
}
|
|
98
157
|
};
|
|
99
158
|
SpyClient.prototype.check = function (query) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).SpyClient=t()}(this,function(){"use strict";function o(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return(Object.assign||function(e){for(var t,n=1,o=arguments.length;n<o;n++)for(var r in t=arguments[n])Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e}).apply(this,e)}var
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).SpyClient=t()}(this,function(){"use strict";function o(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];return(Object.assign||function(e){for(var t=void 0,n=1,o=arguments.length;n<o;n++)for(var r in t=arguments[n])Object.prototype.hasOwnProperty.call(t,r)&&(e[r]=t[r]);return e}).apply(this,e)}var e=navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?)_/),s=e&&e[2]&&+e[2]<14;function f(e){console.error("[SpyClient_log]"+e)}function p(n){return Object.keys(n).map(function(e){var t=n[e];return void 0===t?t="":"string"!=typeof t&&(t=JSON.stringify(t)),encodeURIComponent(e)+"="+encodeURIComponent(t)}).join("&")}function c(e){return"[object Array]"===Object.prototype.toString.call(e)}function t(e){if(this.sample={},this.markCache={},!e.pid)throw new Error("pid is required");this.option={pid:e.pid,lid:e.lid,check:!1!==e.check,sample:e.sample,localCache:e.localCache,logServer:e.logServer||"https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/mwb2.gif?"}}return t.prototype.fetch=function(e,t){window.fetch&&fetch(e,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})},t.prototype.sendPost=function(e){var t=(c(e)?e:[e])[0],n={pid:t.pid,type:t.type,group:t.group},o=this.option.logServer+p(n);!s&&navigator.sendBeacon&&navigator.sendBeacon(o,JSON.stringify(e))||this.fetch(o,e)},t.prototype.handle=function(e){if(this.check(e)){if(e=o({pid:this.option.pid,lid:this.option.lid,ts:Date.now(),group:"common"},e),this.option.localCache&&this.option.localCache.addLog(e),"number"==typeof e.sample){if(Math.random()>e.sample)return}else if("number"==typeof this.option.sample&&Math.random()>this.option.sample)return;return delete e.sample,e}},t.prototype.send=function(e,t){void 0===t&&(t=!1);for(var n=[],o=0,r=c(e)?e:[e];o<r.length;o++){var i=r[o];if((i=this.handle(i))&&(n.push(i),!t)){var a=this.option.logServer+p(i);!s&&navigator.sendBeacon&&navigator.sendBeacon(a)||((new Image).src=a)}}t&&this.sendPost(n)},t.prototype.check=function(e){if(!this.option.check)return!0;var t=["perf","except","dist","count"];if(-1===t.indexOf(e.type))return f("type only is one of "+t.join(", ")),!1;if(e.group&&30<e.group.length)return f("group length execeeds 30"),!1;var n=/^[a-zA-Z0-9-_]{0,30}$/;if("except"===e.type){if("string"!=typeof e.info.msg||!e.info.msg.length)return f("info.msg field must be not empty and is String"),!1}else for(var o=0,r=Object.keys(e.info);o<r.length;o++){var i=r[o];if(!n.test(i))return f("info."+i+" is unexpected. Length must be not more than 30. Supported chars: a-zA-Z0-9-_"),!1;var a=e.info[i];if("dist"===e.type){if(30<a.length)return f("info."+i+" value length execeeds 30 when type == 'dist'"),!1}else if("number"!=typeof a)return f("info."+i+" value must be number"),!1}if(e.dim)for(var s=0,p=Object.keys(e.dim);s<p.length;s++){var c=p[s];if(!n.test(c))return f("dim key ["+c+"] is unexpected. Length must be not more than 30. Supported chars: a-zA-Z0-9-_"),!1;var h=e.dim[c];if(!/^[a-zA-Z0-9\-_\*\.\s\/#\+@\&\u4e00-\u9fa5]{0,30}$/.test(h))return f("dim."+c+" value ["+h+"] is unexpected. Length must be not more than 30. Supported chars: a-zA-Z0-9-_*. /#+@& and Chinese"),!1}return!0},t.prototype.sendPerf=function(e){this.send(o({type:"perf"},e))},t.prototype.sendExcept=function(e){this.send(o({type:"except"},e))},t.prototype.sendDist=function(e){this.send(o({type:"dist"},e))},t.prototype.sendCount=function(e){this.send(o({type:"count"},e))},t.prototype.sendExceptForError=function(e,t){var n=o({},t);n.info=o({},t.info||{},{msg:e.message,stack:e.stack}),this.sendExcept(n)},t.prototype.startMark=function(e){this.markCache[e]={start:Date.now()}},t.prototype.endMark=function(e){return this.markCache[e]?(this.markCache[e].total=Date.now()-this.markCache[e].start,this.markCache[e].total):0},t.prototype.clearMark=function(e){this.markCache[e]&&delete this.markCache[e]},t.prototype.getAllMark=function(){for(var e={},t=0,n=Object.keys(this.markCache);t<n.length;t++){var o=n[t];e[o]=this.markCache[o].total}return e},t.prototype.clearAllMark=function(){this.markCache={}},t});
|
|
@@ -27,7 +27,8 @@ function assign() {
|
|
|
27
27
|
* @author kaivean
|
|
28
28
|
*/
|
|
29
29
|
var defaultLogServer = 'https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/mwb2.gif?';
|
|
30
|
-
var
|
|
30
|
+
var ver = navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?)_/);
|
|
31
|
+
var isLtIos14 = ver && ver[2] && (+ver[2] < 14);
|
|
31
32
|
function err(msg) {
|
|
32
33
|
console.error("[SpyClient_log]" + msg);
|
|
33
34
|
// throw new Error(msg);
|
|
@@ -44,6 +45,9 @@ function stringify(obj) {
|
|
|
44
45
|
return encodeURIComponent(key) + '=' + encodeURIComponent(value);
|
|
45
46
|
}).join('&');
|
|
46
47
|
}
|
|
48
|
+
function isArray(arr) {
|
|
49
|
+
return Object.prototype.toString.call(arr) === '[object Array]';
|
|
50
|
+
}
|
|
47
51
|
var SpyClient = /** @class */ (function () {
|
|
48
52
|
function SpyClient(option) {
|
|
49
53
|
this.sample = {};
|
|
@@ -56,38 +60,93 @@ var SpyClient = /** @class */ (function () {
|
|
|
56
60
|
lid: option.lid,
|
|
57
61
|
check: option.check !== false,
|
|
58
62
|
sample: option.sample,
|
|
63
|
+
localCache: option.localCache,
|
|
59
64
|
logServer: option.logServer || defaultLogServer,
|
|
60
65
|
};
|
|
61
66
|
}
|
|
62
|
-
SpyClient.prototype.
|
|
63
|
-
if (!
|
|
67
|
+
SpyClient.prototype.fetch = function (url, data) {
|
|
68
|
+
if (!window.fetch) {
|
|
64
69
|
return;
|
|
65
70
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
fetch(url, {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
credentials: 'include',
|
|
74
|
+
headers: {
|
|
75
|
+
'Content-Type': 'application/json',
|
|
76
|
+
},
|
|
77
|
+
body: JSON.stringify(data),
|
|
78
|
+
});
|
|
79
|
+
};
|
|
80
|
+
SpyClient.prototype.sendPost = function (data) {
|
|
81
|
+
var logItems = isArray(data) ? data : [data];
|
|
82
|
+
var first = logItems[0];
|
|
83
|
+
// 需要在页面暴漏出来pid等基本信息,方式调试查看基本信息与兼容目前的监控
|
|
84
|
+
var query = {
|
|
85
|
+
pid: first.pid,
|
|
86
|
+
type: first.type,
|
|
87
|
+
group: first.group,
|
|
88
|
+
};
|
|
89
|
+
var url = this.option.logServer + stringify(query);
|
|
90
|
+
if (!(!isLtIos14
|
|
91
|
+
&& navigator.sendBeacon
|
|
92
|
+
&& navigator.sendBeacon(url, JSON.stringify(data)))) {
|
|
93
|
+
this.fetch(url, data);
|
|
71
94
|
}
|
|
72
|
-
|
|
95
|
+
};
|
|
96
|
+
SpyClient.prototype.handle = function (logItem) {
|
|
97
|
+
if (!this.check(logItem)) {
|
|
73
98
|
return;
|
|
74
99
|
}
|
|
75
|
-
|
|
100
|
+
logItem = assign({
|
|
76
101
|
pid: this.option.pid,
|
|
77
102
|
lid: this.option.lid,
|
|
78
103
|
ts: Date.now(),
|
|
79
104
|
group: 'common',
|
|
80
|
-
},
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
//
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
105
|
+
}, logItem);
|
|
106
|
+
if (this.option.localCache) {
|
|
107
|
+
this.option.localCache.addLog(logItem);
|
|
108
|
+
}
|
|
109
|
+
// 当前api设置了抽样,
|
|
110
|
+
if (typeof logItem.sample === 'number') {
|
|
111
|
+
if (Math.random() > logItem.sample) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else if (typeof this.option.sample === 'number' && Math.random() > this.option.sample) { // 否则,用全局抽样
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
delete logItem.sample;
|
|
119
|
+
return logItem;
|
|
120
|
+
};
|
|
121
|
+
SpyClient.prototype.send = function (data, post) {
|
|
122
|
+
if (post === void 0) { post = false; }
|
|
123
|
+
var logItems = isArray(data) ? data : [data];
|
|
124
|
+
var postData = [];
|
|
125
|
+
for (var _i = 0, logItems_1 = logItems; _i < logItems_1.length; _i++) {
|
|
126
|
+
var logItem = logItems_1[_i];
|
|
127
|
+
logItem = this.handle(logItem);
|
|
128
|
+
if (!logItem) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
postData.push(logItem);
|
|
132
|
+
// 期望通过post方式上传日志
|
|
133
|
+
if (post) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
var url = this.option.logServer + stringify(logItem);
|
|
137
|
+
// 目前服务器端支持sendBeacon的post请求,可以优先采用,该api可以降低打点丢失率
|
|
138
|
+
// 但是ios有些问题:在webkit浏览内核环境下,beacon requests的请求方式存在证书验证的bug,发送失败但返回正确.
|
|
139
|
+
// 修复说明在如下链接中:https://bugs.webkit.org/show_bug.cgi?id=193508
|
|
140
|
+
// 但是目前为止,在iOS12.2版本中该问题依旧存在
|
|
141
|
+
// 2021-11-11: 发现ios 14可以送,故小于14的不发送
|
|
142
|
+
if (!(!isLtIos14
|
|
143
|
+
&& navigator.sendBeacon
|
|
144
|
+
&& navigator.sendBeacon(url))) {
|
|
145
|
+
(new Image()).src = url;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (post) {
|
|
149
|
+
this.sendPost(postData);
|
|
91
150
|
}
|
|
92
151
|
};
|
|
93
152
|
SpyClient.prototype.check = function (query) {
|
package/dist/spy-client.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { Module, SpyClientOption, FIDCB, LCPCB, LayoutShiftCB, PageLongtaskCB, L
|
|
|
7
7
|
export default class SpyClient extends SpyClientBasic {
|
|
8
8
|
private readonly modules;
|
|
9
9
|
constructor(option: SpyClientOption);
|
|
10
|
+
handleHead(): void;
|
|
10
11
|
listenFID(cb: FIDCB): void;
|
|
11
12
|
listenLayoutShift(cb: LayoutShiftCB): void;
|
|
12
13
|
listenLCP(cb: LCPCB): void;
|
package/dist/spy-client.esm.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/*! *****************************************************************************
|
|
2
|
-
Copyright (c) Microsoft Corporation.
|
|
2
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
4
|
+
this file except in compliance with the License. You may obtain a copy of the
|
|
5
|
+
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
3
6
|
|
|
4
|
-
|
|
5
|
-
|
|
7
|
+
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
8
|
+
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
9
|
+
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
10
|
+
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
10
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
11
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
12
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
13
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
12
|
+
See the Apache Version 2.0 License for specific language governing permissions
|
|
13
|
+
and limitations under the License.
|
|
14
14
|
***************************************************************************** */
|
|
15
15
|
/* global Reflect, Promise */
|
|
16
16
|
|
|
@@ -132,7 +132,8 @@ function getxpath(el) {
|
|
|
132
132
|
* @author kaivean
|
|
133
133
|
*/
|
|
134
134
|
var defaultLogServer = 'https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/mwb2.gif?';
|
|
135
|
-
var
|
|
135
|
+
var ver = navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?)_/);
|
|
136
|
+
var isLtIos14 = ver && ver[2] && (+ver[2] < 14);
|
|
136
137
|
function err(msg) {
|
|
137
138
|
console.error("[SpyClient_log]" + msg);
|
|
138
139
|
// throw new Error(msg);
|
|
@@ -149,6 +150,9 @@ function stringify(obj) {
|
|
|
149
150
|
return encodeURIComponent(key) + '=' + encodeURIComponent(value);
|
|
150
151
|
}).join('&');
|
|
151
152
|
}
|
|
153
|
+
function isArray(arr) {
|
|
154
|
+
return Object.prototype.toString.call(arr) === '[object Array]';
|
|
155
|
+
}
|
|
152
156
|
var SpyClient$1 = /** @class */ (function () {
|
|
153
157
|
function SpyClient(option) {
|
|
154
158
|
this.sample = {};
|
|
@@ -161,38 +165,93 @@ var SpyClient$1 = /** @class */ (function () {
|
|
|
161
165
|
lid: option.lid,
|
|
162
166
|
check: option.check !== false,
|
|
163
167
|
sample: option.sample,
|
|
168
|
+
localCache: option.localCache,
|
|
164
169
|
logServer: option.logServer || defaultLogServer,
|
|
165
170
|
};
|
|
166
171
|
}
|
|
167
|
-
SpyClient.prototype.
|
|
168
|
-
if (!
|
|
172
|
+
SpyClient.prototype.fetch = function (url, data) {
|
|
173
|
+
if (!window.fetch) {
|
|
169
174
|
return;
|
|
170
175
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
+
fetch(url, {
|
|
177
|
+
method: 'POST',
|
|
178
|
+
credentials: 'include',
|
|
179
|
+
headers: {
|
|
180
|
+
'Content-Type': 'application/json',
|
|
181
|
+
},
|
|
182
|
+
body: JSON.stringify(data),
|
|
183
|
+
});
|
|
184
|
+
};
|
|
185
|
+
SpyClient.prototype.sendPost = function (data) {
|
|
186
|
+
var logItems = isArray(data) ? data : [data];
|
|
187
|
+
var first = logItems[0];
|
|
188
|
+
// 需要在页面暴漏出来pid等基本信息,方式调试查看基本信息与兼容目前的监控
|
|
189
|
+
var query = {
|
|
190
|
+
pid: first.pid,
|
|
191
|
+
type: first.type,
|
|
192
|
+
group: first.group,
|
|
193
|
+
};
|
|
194
|
+
var url = this.option.logServer + stringify(query);
|
|
195
|
+
if (!(!isLtIos14
|
|
196
|
+
&& navigator.sendBeacon
|
|
197
|
+
&& navigator.sendBeacon(url, JSON.stringify(data)))) {
|
|
198
|
+
this.fetch(url, data);
|
|
176
199
|
}
|
|
177
|
-
|
|
200
|
+
};
|
|
201
|
+
SpyClient.prototype.handle = function (logItem) {
|
|
202
|
+
if (!this.check(logItem)) {
|
|
178
203
|
return;
|
|
179
204
|
}
|
|
180
|
-
|
|
205
|
+
logItem = assign({
|
|
181
206
|
pid: this.option.pid,
|
|
182
207
|
lid: this.option.lid,
|
|
183
208
|
ts: Date.now(),
|
|
184
209
|
group: 'common',
|
|
185
|
-
},
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
//
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
210
|
+
}, logItem);
|
|
211
|
+
if (this.option.localCache) {
|
|
212
|
+
this.option.localCache.addLog(logItem);
|
|
213
|
+
}
|
|
214
|
+
// 当前api设置了抽样,
|
|
215
|
+
if (typeof logItem.sample === 'number') {
|
|
216
|
+
if (Math.random() > logItem.sample) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else if (typeof this.option.sample === 'number' && Math.random() > this.option.sample) { // 否则,用全局抽样
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
delete logItem.sample;
|
|
224
|
+
return logItem;
|
|
225
|
+
};
|
|
226
|
+
SpyClient.prototype.send = function (data, post) {
|
|
227
|
+
if (post === void 0) { post = false; }
|
|
228
|
+
var logItems = isArray(data) ? data : [data];
|
|
229
|
+
var postData = [];
|
|
230
|
+
for (var _i = 0, logItems_1 = logItems; _i < logItems_1.length; _i++) {
|
|
231
|
+
var logItem = logItems_1[_i];
|
|
232
|
+
logItem = this.handle(logItem);
|
|
233
|
+
if (!logItem) {
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
postData.push(logItem);
|
|
237
|
+
// 期望通过post方式上传日志
|
|
238
|
+
if (post) {
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
var url = this.option.logServer + stringify(logItem);
|
|
242
|
+
// 目前服务器端支持sendBeacon的post请求,可以优先采用,该api可以降低打点丢失率
|
|
243
|
+
// 但是ios有些问题:在webkit浏览内核环境下,beacon requests的请求方式存在证书验证的bug,发送失败但返回正确.
|
|
244
|
+
// 修复说明在如下链接中:https://bugs.webkit.org/show_bug.cgi?id=193508
|
|
245
|
+
// 但是目前为止,在iOS12.2版本中该问题依旧存在
|
|
246
|
+
// 2021-11-11: 发现ios 14可以送,故小于14的不发送
|
|
247
|
+
if (!(!isLtIos14
|
|
248
|
+
&& navigator.sendBeacon
|
|
249
|
+
&& navigator.sendBeacon(url))) {
|
|
250
|
+
(new Image()).src = url;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (post) {
|
|
254
|
+
this.sendPost(postData);
|
|
196
255
|
}
|
|
197
256
|
};
|
|
198
257
|
SpyClient.prototype.check = function (query) {
|
|
@@ -1307,8 +1366,25 @@ var SpyClient = /** @class */ (function (_super) {
|
|
|
1307
1366
|
document.addEventListener('visibilitychange', _this.visibilitychangeCB);
|
|
1308
1367
|
window.addEventListener('beforeunload', _this.leave, false);
|
|
1309
1368
|
window.addEventListener('unload', _this.leave, false);
|
|
1369
|
+
_this.handleHead();
|
|
1310
1370
|
return _this;
|
|
1311
1371
|
}
|
|
1372
|
+
SpyClient.prototype.handleHead = function () {
|
|
1373
|
+
var _this = this;
|
|
1374
|
+
if (this.option.localCache) {
|
|
1375
|
+
var spyHead = window.__spyHead;
|
|
1376
|
+
if (spyHead && spyHead.winerrors) {
|
|
1377
|
+
for (var index = 0; index < spyHead.winerrors.length; index++) {
|
|
1378
|
+
var obj = spyHead.winerrors[index];
|
|
1379
|
+
this.option.localCache.addLog(obj);
|
|
1380
|
+
}
|
|
1381
|
+
// Head发送的异常,也保存一份到本地,主要是JS错误和资源加载异常
|
|
1382
|
+
spyHead.interceptor = function (obj) {
|
|
1383
|
+
_this.option.localCache.addLog(obj);
|
|
1384
|
+
};
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1312
1388
|
SpyClient.prototype.listenFID = function (cb) {
|
|
1313
1389
|
this.invoke('listenFID', cb);
|
|
1314
1390
|
};
|