spy-client 2.1.2 → 2.1.8
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 +8 -3
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/basicSpec.ts.html +1 -1
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/checkSpec.ts.html +1 -1
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/headSpec.ts.html +1 -1
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/index.html +1 -1
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/markSpec.ts.html +1 -1
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/metricSpec.ts.html +1 -1
- package/coverage/Chrome 96.0.4664.110 (Mac OS 10.15.7)/html/base.css +224 -0
- package/coverage/Chrome 96.0.4664.110 (Mac OS 10.15.7)/html/basicSpec.ts.html +740 -0
- package/coverage/Chrome 96.0.4664.110 (Mac OS 10.15.7)/html/block-navigation.js +79 -0
- package/coverage/Chrome 96.0.4664.110 (Mac OS 10.15.7)/html/checkSpec.ts.html +479 -0
- package/coverage/Chrome 96.0.4664.110 (Mac OS 10.15.7)/html/favicon.png +0 -0
- package/coverage/Chrome 96.0.4664.110 (Mac OS 10.15.7)/html/headSpec.ts.html +695 -0
- package/coverage/Chrome 96.0.4664.110 (Mac OS 10.15.7)/html/index.html +171 -0
- package/coverage/Chrome 96.0.4664.110 (Mac OS 10.15.7)/html/markSpec.ts.html +284 -0
- package/coverage/Chrome 96.0.4664.110 (Mac OS 10.15.7)/html/metricSpec.ts.html +977 -0
- package/coverage/Chrome 96.0.4664.110 (Mac OS 10.15.7)/html/prettify.css +1 -0
- package/coverage/Chrome 96.0.4664.110 (Mac OS 10.15.7)/html/prettify.js +2 -0
- package/coverage/Chrome 96.0.4664.110 (Mac OS 10.15.7)/html/sort-arrow-sprite.png +0 -0
- package/coverage/Chrome 96.0.4664.110 (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 +3 -2
- package/dist/spy-client-basic.esm.js +55 -46
- package/dist/spy-client-basic.iife.js +55 -46
- package/dist/spy-client-basic.iife.min.js +1 -1
- package/dist/spy-client-basic.js +55 -46
- package/dist/spy-client-basic.min.js +1 -1
- package/dist/spy-client-basic.mjs +55 -46
- package/dist/spy-client.d.ts +1 -0
- package/dist/spy-client.esm.js +72 -46
- package/dist/spy-client.iife.js +72 -46
- package/dist/spy-client.iife.min.js +1 -1
- package/dist/spy-client.js +72 -46
- package/dist/spy-client.min.js +1 -1
- package/dist/spy-client.mjs +72 -46
- package/dist/spy-head.js +46 -34
- package/dist/spy-head.min.js +1 -1
- package/dist/spy-local-cache.js +28 -41
- package/dist/spy-local-cache.min.js +1 -1
- package/example/index.html +2 -0
- package/example/local-cache.html +77 -15
- package/package.json +3 -3
- 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 +65 -58
- package/src/spy-client.ts +19 -1
- package/src/spy-local-cache.ts +12 -2
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
|
-
|
|
36
|
+
// 基础版本兼容非浏览器环境
|
|
37
|
+
var ver = navigator && navigator.userAgent ? navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?)_/) : '';
|
|
37
38
|
var isLtIos14 = ver && ver[2] && (+ver[2] < 14);
|
|
38
39
|
function err(msg) {
|
|
39
40
|
console.error("[SpyClient_log]" + msg);
|
|
@@ -66,42 +67,23 @@
|
|
|
66
67
|
lid: option.lid,
|
|
67
68
|
check: option.check !== false,
|
|
68
69
|
sample: option.sample,
|
|
70
|
+
localCache: option.localCache,
|
|
69
71
|
logServer: option.logServer || defaultLogServer,
|
|
70
72
|
};
|
|
71
73
|
}
|
|
72
|
-
SpyClient.prototype.fetch = function (url, data) {
|
|
73
|
-
if (!window.fetch) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
fetch(url, {
|
|
77
|
-
method: 'POST',
|
|
78
|
-
credentials: 'include',
|
|
79
|
-
headers: {
|
|
80
|
-
'Content-Type': 'application/json'
|
|
81
|
-
},
|
|
82
|
-
body: JSON.stringify(data)
|
|
83
|
-
});
|
|
84
|
-
};
|
|
85
|
-
SpyClient.prototype.sendPost = function (data) {
|
|
86
|
-
var logItems = isArray(data) ? data : [data];
|
|
87
|
-
var first = logItems[0];
|
|
88
|
-
// 需要在页面暴漏出来pid等基本信息,方式调试查看基本信息与兼容目前的监控
|
|
89
|
-
var query = {
|
|
90
|
-
pid: first.pid,
|
|
91
|
-
type: first.type,
|
|
92
|
-
group: first.group,
|
|
93
|
-
};
|
|
94
|
-
var url = this.option.logServer + stringify(query);
|
|
95
|
-
if (!(!isLtIos14
|
|
96
|
-
&& navigator.sendBeacon
|
|
97
|
-
&& navigator.sendBeacon(url, JSON.stringify(data)))) {
|
|
98
|
-
this.fetch(url, data);
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
74
|
SpyClient.prototype.handle = function (logItem) {
|
|
102
75
|
if (!this.check(logItem)) {
|
|
103
76
|
return;
|
|
104
77
|
}
|
|
78
|
+
logItem = assign({
|
|
79
|
+
pid: this.option.pid,
|
|
80
|
+
lid: this.option.lid,
|
|
81
|
+
ts: Date.now(),
|
|
82
|
+
group: 'common',
|
|
83
|
+
}, logItem);
|
|
84
|
+
if (this.option.localCache) {
|
|
85
|
+
this.option.localCache.addLog(logItem);
|
|
86
|
+
}
|
|
105
87
|
// 当前api设置了抽样,
|
|
106
88
|
if (typeof logItem.sample === 'number') {
|
|
107
89
|
if (Math.random() > logItem.sample) {
|
|
@@ -111,12 +93,6 @@
|
|
|
111
93
|
else if (typeof this.option.sample === 'number' && Math.random() > this.option.sample) { // 否则,用全局抽样
|
|
112
94
|
return;
|
|
113
95
|
}
|
|
114
|
-
logItem = assign({
|
|
115
|
-
pid: this.option.pid,
|
|
116
|
-
lid: this.option.lid,
|
|
117
|
-
ts: Date.now(),
|
|
118
|
-
group: 'common',
|
|
119
|
-
}, logItem);
|
|
120
96
|
delete logItem.sample;
|
|
121
97
|
return logItem;
|
|
122
98
|
};
|
|
@@ -136,16 +112,7 @@
|
|
|
136
112
|
continue;
|
|
137
113
|
}
|
|
138
114
|
var url = this.option.logServer + stringify(logItem);
|
|
139
|
-
|
|
140
|
-
// 但是ios有些问题:在webkit浏览内核环境下,beacon requests的请求方式存在证书验证的bug,发送失败但返回正确.
|
|
141
|
-
// 修复说明在如下链接中:https://bugs.webkit.org/show_bug.cgi?id=193508
|
|
142
|
-
// 但是目前为止,在iOS12.2版本中该问题依旧存在
|
|
143
|
-
// 2021-11-11: 发现ios 14可以送,故小于14的不发送
|
|
144
|
-
if (!(!isLtIos14
|
|
145
|
-
&& navigator.sendBeacon
|
|
146
|
-
&& navigator.sendBeacon(url))) {
|
|
147
|
-
(new Image()).src = url;
|
|
148
|
-
}
|
|
115
|
+
this.request(url);
|
|
149
116
|
}
|
|
150
117
|
if (post) {
|
|
151
118
|
this.sendPost(postData);
|
|
@@ -290,6 +257,48 @@
|
|
|
290
257
|
SpyClient.prototype.clearAllMark = function () {
|
|
291
258
|
this.markCache = {};
|
|
292
259
|
};
|
|
260
|
+
// send(data, true) 也能以post发送,但是会有严格校验
|
|
261
|
+
// sendPost能以post发送,但没有校验
|
|
262
|
+
SpyClient.prototype.sendPost = function (data) {
|
|
263
|
+
var logItems = isArray(data) ? data : [data];
|
|
264
|
+
var first = logItems[0];
|
|
265
|
+
// 需要在页面暴漏出来pid等基本信息,方式调试查看基本信息与兼容目前的监控
|
|
266
|
+
var query = {
|
|
267
|
+
pid: first.pid,
|
|
268
|
+
type: first.type,
|
|
269
|
+
group: first.group,
|
|
270
|
+
};
|
|
271
|
+
var url = this.option.logServer + stringify(query);
|
|
272
|
+
this.request(url, data);
|
|
273
|
+
};
|
|
274
|
+
// 有data时,意味着要用post发送请求
|
|
275
|
+
SpyClient.prototype.request = function (url, data) {
|
|
276
|
+
if (!(!isLtIos14
|
|
277
|
+
&& navigator
|
|
278
|
+
&& navigator.sendBeacon
|
|
279
|
+
&& navigator.sendBeacon(url, data ? JSON.stringify(data) : undefined))) {
|
|
280
|
+
if (data) {
|
|
281
|
+
this.fetch(url, data);
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
(new Image()).src = url;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
SpyClient.prototype.fetch = function (url, data) {
|
|
289
|
+
if (!fetch) {
|
|
290
|
+
err('Global fetch method doesn\'t exist');
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
fetch(url, {
|
|
294
|
+
method: 'POST',
|
|
295
|
+
credentials: 'include',
|
|
296
|
+
headers: {
|
|
297
|
+
'Content-Type': 'application/json',
|
|
298
|
+
},
|
|
299
|
+
body: JSON.stringify(data),
|
|
300
|
+
});
|
|
301
|
+
};
|
|
293
302
|
return SpyClient;
|
|
294
303
|
}());
|
|
295
304
|
|
|
@@ -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=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 (.*?)_/),
|
|
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&&navigator.userAgent?navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?)_/):"",n=e&&e[2]&&+e[2]<14;function f(e){console.error("[SpyClient_log]"+e)}function a(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 p(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.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=p(e)?e:[e];o<r.length;o++){var i=r[o];if((i=this.handle(i))&&(n.push(i),!t)){var s=this.option.logServer+a(i);this.request(s)}}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 s=e.info[i];if("dist"===e.type){if(30<s.length)return f("info."+i+" value length execeeds 30 when type == 'dist'"),!1}else if("number"!=typeof s)return f("info."+i+" value must be number"),!1}if(e.dim)for(var a=0,p=Object.keys(e.dim);a<p.length;a++){var c=p[a];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.prototype.sendPost=function(e){var t=(p(e)?e:[e])[0],n={pid:t.pid,type:t.type,group:t.group},o=this.option.logServer+a(n);this.request(o,e)},t.prototype.request=function(e,t){!n&&navigator&&navigator.sendBeacon&&navigator.sendBeacon(e,t?JSON.stringify(t):void 0)||(t?this.fetch(e,t):(new Image).src=e)},t.prototype.fetch=function(e,t){fetch?fetch(e,{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}):f("Global fetch method doesn't exist")},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
|
-
|
|
30
|
+
// 基础版本兼容非浏览器环境
|
|
31
|
+
var ver = navigator && navigator.userAgent ? navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?)_/) : '';
|
|
31
32
|
var isLtIos14 = ver && ver[2] && (+ver[2] < 14);
|
|
32
33
|
function err(msg) {
|
|
33
34
|
console.error("[SpyClient_log]" + msg);
|
|
@@ -60,42 +61,23 @@ var SpyClient = /** @class */ (function () {
|
|
|
60
61
|
lid: option.lid,
|
|
61
62
|
check: option.check !== false,
|
|
62
63
|
sample: option.sample,
|
|
64
|
+
localCache: option.localCache,
|
|
63
65
|
logServer: option.logServer || defaultLogServer,
|
|
64
66
|
};
|
|
65
67
|
}
|
|
66
|
-
SpyClient.prototype.fetch = function (url, data) {
|
|
67
|
-
if (!window.fetch) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
fetch(url, {
|
|
71
|
-
method: 'POST',
|
|
72
|
-
credentials: 'include',
|
|
73
|
-
headers: {
|
|
74
|
-
'Content-Type': 'application/json'
|
|
75
|
-
},
|
|
76
|
-
body: JSON.stringify(data)
|
|
77
|
-
});
|
|
78
|
-
};
|
|
79
|
-
SpyClient.prototype.sendPost = function (data) {
|
|
80
|
-
var logItems = isArray(data) ? data : [data];
|
|
81
|
-
var first = logItems[0];
|
|
82
|
-
// 需要在页面暴漏出来pid等基本信息,方式调试查看基本信息与兼容目前的监控
|
|
83
|
-
var query = {
|
|
84
|
-
pid: first.pid,
|
|
85
|
-
type: first.type,
|
|
86
|
-
group: first.group,
|
|
87
|
-
};
|
|
88
|
-
var url = this.option.logServer + stringify(query);
|
|
89
|
-
if (!(!isLtIos14
|
|
90
|
-
&& navigator.sendBeacon
|
|
91
|
-
&& navigator.sendBeacon(url, JSON.stringify(data)))) {
|
|
92
|
-
this.fetch(url, data);
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
68
|
SpyClient.prototype.handle = function (logItem) {
|
|
96
69
|
if (!this.check(logItem)) {
|
|
97
70
|
return;
|
|
98
71
|
}
|
|
72
|
+
logItem = assign({
|
|
73
|
+
pid: this.option.pid,
|
|
74
|
+
lid: this.option.lid,
|
|
75
|
+
ts: Date.now(),
|
|
76
|
+
group: 'common',
|
|
77
|
+
}, logItem);
|
|
78
|
+
if (this.option.localCache) {
|
|
79
|
+
this.option.localCache.addLog(logItem);
|
|
80
|
+
}
|
|
99
81
|
// 当前api设置了抽样,
|
|
100
82
|
if (typeof logItem.sample === 'number') {
|
|
101
83
|
if (Math.random() > logItem.sample) {
|
|
@@ -105,12 +87,6 @@ var SpyClient = /** @class */ (function () {
|
|
|
105
87
|
else if (typeof this.option.sample === 'number' && Math.random() > this.option.sample) { // 否则,用全局抽样
|
|
106
88
|
return;
|
|
107
89
|
}
|
|
108
|
-
logItem = assign({
|
|
109
|
-
pid: this.option.pid,
|
|
110
|
-
lid: this.option.lid,
|
|
111
|
-
ts: Date.now(),
|
|
112
|
-
group: 'common',
|
|
113
|
-
}, logItem);
|
|
114
90
|
delete logItem.sample;
|
|
115
91
|
return logItem;
|
|
116
92
|
};
|
|
@@ -130,16 +106,7 @@ var SpyClient = /** @class */ (function () {
|
|
|
130
106
|
continue;
|
|
131
107
|
}
|
|
132
108
|
var url = this.option.logServer + stringify(logItem);
|
|
133
|
-
|
|
134
|
-
// 但是ios有些问题:在webkit浏览内核环境下,beacon requests的请求方式存在证书验证的bug,发送失败但返回正确.
|
|
135
|
-
// 修复说明在如下链接中:https://bugs.webkit.org/show_bug.cgi?id=193508
|
|
136
|
-
// 但是目前为止,在iOS12.2版本中该问题依旧存在
|
|
137
|
-
// 2021-11-11: 发现ios 14可以送,故小于14的不发送
|
|
138
|
-
if (!(!isLtIos14
|
|
139
|
-
&& navigator.sendBeacon
|
|
140
|
-
&& navigator.sendBeacon(url))) {
|
|
141
|
-
(new Image()).src = url;
|
|
142
|
-
}
|
|
109
|
+
this.request(url);
|
|
143
110
|
}
|
|
144
111
|
if (post) {
|
|
145
112
|
this.sendPost(postData);
|
|
@@ -284,6 +251,48 @@ var SpyClient = /** @class */ (function () {
|
|
|
284
251
|
SpyClient.prototype.clearAllMark = function () {
|
|
285
252
|
this.markCache = {};
|
|
286
253
|
};
|
|
254
|
+
// send(data, true) 也能以post发送,但是会有严格校验
|
|
255
|
+
// sendPost能以post发送,但没有校验
|
|
256
|
+
SpyClient.prototype.sendPost = function (data) {
|
|
257
|
+
var logItems = isArray(data) ? data : [data];
|
|
258
|
+
var first = logItems[0];
|
|
259
|
+
// 需要在页面暴漏出来pid等基本信息,方式调试查看基本信息与兼容目前的监控
|
|
260
|
+
var query = {
|
|
261
|
+
pid: first.pid,
|
|
262
|
+
type: first.type,
|
|
263
|
+
group: first.group,
|
|
264
|
+
};
|
|
265
|
+
var url = this.option.logServer + stringify(query);
|
|
266
|
+
this.request(url, data);
|
|
267
|
+
};
|
|
268
|
+
// 有data时,意味着要用post发送请求
|
|
269
|
+
SpyClient.prototype.request = function (url, data) {
|
|
270
|
+
if (!(!isLtIos14
|
|
271
|
+
&& navigator
|
|
272
|
+
&& navigator.sendBeacon
|
|
273
|
+
&& navigator.sendBeacon(url, data ? JSON.stringify(data) : undefined))) {
|
|
274
|
+
if (data) {
|
|
275
|
+
this.fetch(url, data);
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
(new Image()).src = url;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
SpyClient.prototype.fetch = function (url, data) {
|
|
283
|
+
if (!fetch) {
|
|
284
|
+
err('Global fetch method doesn\'t exist');
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
fetch(url, {
|
|
288
|
+
method: 'POST',
|
|
289
|
+
credentials: 'include',
|
|
290
|
+
headers: {
|
|
291
|
+
'Content-Type': 'application/json',
|
|
292
|
+
},
|
|
293
|
+
body: JSON.stringify(data),
|
|
294
|
+
});
|
|
295
|
+
};
|
|
287
296
|
return SpyClient;
|
|
288
297
|
}());
|
|
289
298
|
|
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
|
@@ -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
|
-
|
|
135
|
+
// 基础版本兼容非浏览器环境
|
|
136
|
+
var ver = navigator && navigator.userAgent ? navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?)_/) : '';
|
|
136
137
|
var isLtIos14 = ver && ver[2] && (+ver[2] < 14);
|
|
137
138
|
function err(msg) {
|
|
138
139
|
console.error("[SpyClient_log]" + msg);
|
|
@@ -165,42 +166,23 @@ var SpyClient$1 = /** @class */ (function () {
|
|
|
165
166
|
lid: option.lid,
|
|
166
167
|
check: option.check !== false,
|
|
167
168
|
sample: option.sample,
|
|
169
|
+
localCache: option.localCache,
|
|
168
170
|
logServer: option.logServer || defaultLogServer,
|
|
169
171
|
};
|
|
170
172
|
}
|
|
171
|
-
SpyClient.prototype.fetch = function (url, data) {
|
|
172
|
-
if (!window.fetch) {
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
fetch(url, {
|
|
176
|
-
method: 'POST',
|
|
177
|
-
credentials: 'include',
|
|
178
|
-
headers: {
|
|
179
|
-
'Content-Type': 'application/json'
|
|
180
|
-
},
|
|
181
|
-
body: JSON.stringify(data)
|
|
182
|
-
});
|
|
183
|
-
};
|
|
184
|
-
SpyClient.prototype.sendPost = function (data) {
|
|
185
|
-
var logItems = isArray(data) ? data : [data];
|
|
186
|
-
var first = logItems[0];
|
|
187
|
-
// 需要在页面暴漏出来pid等基本信息,方式调试查看基本信息与兼容目前的监控
|
|
188
|
-
var query = {
|
|
189
|
-
pid: first.pid,
|
|
190
|
-
type: first.type,
|
|
191
|
-
group: first.group,
|
|
192
|
-
};
|
|
193
|
-
var url = this.option.logServer + stringify(query);
|
|
194
|
-
if (!(!isLtIos14
|
|
195
|
-
&& navigator.sendBeacon
|
|
196
|
-
&& navigator.sendBeacon(url, JSON.stringify(data)))) {
|
|
197
|
-
this.fetch(url, data);
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
173
|
SpyClient.prototype.handle = function (logItem) {
|
|
201
174
|
if (!this.check(logItem)) {
|
|
202
175
|
return;
|
|
203
176
|
}
|
|
177
|
+
logItem = assign({
|
|
178
|
+
pid: this.option.pid,
|
|
179
|
+
lid: this.option.lid,
|
|
180
|
+
ts: Date.now(),
|
|
181
|
+
group: 'common',
|
|
182
|
+
}, logItem);
|
|
183
|
+
if (this.option.localCache) {
|
|
184
|
+
this.option.localCache.addLog(logItem);
|
|
185
|
+
}
|
|
204
186
|
// 当前api设置了抽样,
|
|
205
187
|
if (typeof logItem.sample === 'number') {
|
|
206
188
|
if (Math.random() > logItem.sample) {
|
|
@@ -210,12 +192,6 @@ var SpyClient$1 = /** @class */ (function () {
|
|
|
210
192
|
else if (typeof this.option.sample === 'number' && Math.random() > this.option.sample) { // 否则,用全局抽样
|
|
211
193
|
return;
|
|
212
194
|
}
|
|
213
|
-
logItem = assign({
|
|
214
|
-
pid: this.option.pid,
|
|
215
|
-
lid: this.option.lid,
|
|
216
|
-
ts: Date.now(),
|
|
217
|
-
group: 'common',
|
|
218
|
-
}, logItem);
|
|
219
195
|
delete logItem.sample;
|
|
220
196
|
return logItem;
|
|
221
197
|
};
|
|
@@ -235,16 +211,7 @@ var SpyClient$1 = /** @class */ (function () {
|
|
|
235
211
|
continue;
|
|
236
212
|
}
|
|
237
213
|
var url = this.option.logServer + stringify(logItem);
|
|
238
|
-
|
|
239
|
-
// 但是ios有些问题:在webkit浏览内核环境下,beacon requests的请求方式存在证书验证的bug,发送失败但返回正确.
|
|
240
|
-
// 修复说明在如下链接中:https://bugs.webkit.org/show_bug.cgi?id=193508
|
|
241
|
-
// 但是目前为止,在iOS12.2版本中该问题依旧存在
|
|
242
|
-
// 2021-11-11: 发现ios 14可以送,故小于14的不发送
|
|
243
|
-
if (!(!isLtIos14
|
|
244
|
-
&& navigator.sendBeacon
|
|
245
|
-
&& navigator.sendBeacon(url))) {
|
|
246
|
-
(new Image()).src = url;
|
|
247
|
-
}
|
|
214
|
+
this.request(url);
|
|
248
215
|
}
|
|
249
216
|
if (post) {
|
|
250
217
|
this.sendPost(postData);
|
|
@@ -389,6 +356,48 @@ var SpyClient$1 = /** @class */ (function () {
|
|
|
389
356
|
SpyClient.prototype.clearAllMark = function () {
|
|
390
357
|
this.markCache = {};
|
|
391
358
|
};
|
|
359
|
+
// send(data, true) 也能以post发送,但是会有严格校验
|
|
360
|
+
// sendPost能以post发送,但没有校验
|
|
361
|
+
SpyClient.prototype.sendPost = function (data) {
|
|
362
|
+
var logItems = isArray(data) ? data : [data];
|
|
363
|
+
var first = logItems[0];
|
|
364
|
+
// 需要在页面暴漏出来pid等基本信息,方式调试查看基本信息与兼容目前的监控
|
|
365
|
+
var query = {
|
|
366
|
+
pid: first.pid,
|
|
367
|
+
type: first.type,
|
|
368
|
+
group: first.group,
|
|
369
|
+
};
|
|
370
|
+
var url = this.option.logServer + stringify(query);
|
|
371
|
+
this.request(url, data);
|
|
372
|
+
};
|
|
373
|
+
// 有data时,意味着要用post发送请求
|
|
374
|
+
SpyClient.prototype.request = function (url, data) {
|
|
375
|
+
if (!(!isLtIos14
|
|
376
|
+
&& navigator
|
|
377
|
+
&& navigator.sendBeacon
|
|
378
|
+
&& navigator.sendBeacon(url, data ? JSON.stringify(data) : undefined))) {
|
|
379
|
+
if (data) {
|
|
380
|
+
this.fetch(url, data);
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
(new Image()).src = url;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
SpyClient.prototype.fetch = function (url, data) {
|
|
388
|
+
if (!fetch) {
|
|
389
|
+
err('Global fetch method doesn\'t exist');
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
fetch(url, {
|
|
393
|
+
method: 'POST',
|
|
394
|
+
credentials: 'include',
|
|
395
|
+
headers: {
|
|
396
|
+
'Content-Type': 'application/json',
|
|
397
|
+
},
|
|
398
|
+
body: JSON.stringify(data),
|
|
399
|
+
});
|
|
400
|
+
};
|
|
392
401
|
return SpyClient;
|
|
393
402
|
}());
|
|
394
403
|
|
|
@@ -1362,8 +1371,25 @@ var SpyClient = /** @class */ (function (_super) {
|
|
|
1362
1371
|
document.addEventListener('visibilitychange', _this.visibilitychangeCB);
|
|
1363
1372
|
window.addEventListener('beforeunload', _this.leave, false);
|
|
1364
1373
|
window.addEventListener('unload', _this.leave, false);
|
|
1374
|
+
_this.handleHead();
|
|
1365
1375
|
return _this;
|
|
1366
1376
|
}
|
|
1377
|
+
SpyClient.prototype.handleHead = function () {
|
|
1378
|
+
var _this = this;
|
|
1379
|
+
if (this.option.localCache) {
|
|
1380
|
+
var spyHead = window.__spyHead;
|
|
1381
|
+
if (spyHead && spyHead.winerrors) {
|
|
1382
|
+
for (var index = 0; index < spyHead.winerrors.length; index++) {
|
|
1383
|
+
var obj = spyHead.winerrors[index];
|
|
1384
|
+
this.option.localCache.addLog(obj);
|
|
1385
|
+
}
|
|
1386
|
+
// Head发送的异常,也保存一份到本地,主要是JS错误和资源加载异常
|
|
1387
|
+
spyHead.interceptor = function (obj) {
|
|
1388
|
+
_this.option.localCache.addLog(obj);
|
|
1389
|
+
};
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
};
|
|
1367
1393
|
SpyClient.prototype.listenFID = function (cb) {
|
|
1368
1394
|
this.invoke('listenFID', cb);
|
|
1369
1395
|
};
|
package/dist/spy-client.iife.js
CHANGED
|
@@ -135,7 +135,8 @@ var SpyClient = (function () {
|
|
|
135
135
|
* @author kaivean
|
|
136
136
|
*/
|
|
137
137
|
var defaultLogServer = 'https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/mwb2.gif?';
|
|
138
|
-
|
|
138
|
+
// 基础版本兼容非浏览器环境
|
|
139
|
+
var ver = navigator && navigator.userAgent ? navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?)_/) : '';
|
|
139
140
|
var isLtIos14 = ver && ver[2] && (+ver[2] < 14);
|
|
140
141
|
function err(msg) {
|
|
141
142
|
console.error("[SpyClient_log]" + msg);
|
|
@@ -168,42 +169,23 @@ var SpyClient = (function () {
|
|
|
168
169
|
lid: option.lid,
|
|
169
170
|
check: option.check !== false,
|
|
170
171
|
sample: option.sample,
|
|
172
|
+
localCache: option.localCache,
|
|
171
173
|
logServer: option.logServer || defaultLogServer,
|
|
172
174
|
};
|
|
173
175
|
}
|
|
174
|
-
SpyClient.prototype.fetch = function (url, data) {
|
|
175
|
-
if (!window.fetch) {
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
fetch(url, {
|
|
179
|
-
method: 'POST',
|
|
180
|
-
credentials: 'include',
|
|
181
|
-
headers: {
|
|
182
|
-
'Content-Type': 'application/json'
|
|
183
|
-
},
|
|
184
|
-
body: JSON.stringify(data)
|
|
185
|
-
});
|
|
186
|
-
};
|
|
187
|
-
SpyClient.prototype.sendPost = function (data) {
|
|
188
|
-
var logItems = isArray(data) ? data : [data];
|
|
189
|
-
var first = logItems[0];
|
|
190
|
-
// 需要在页面暴漏出来pid等基本信息,方式调试查看基本信息与兼容目前的监控
|
|
191
|
-
var query = {
|
|
192
|
-
pid: first.pid,
|
|
193
|
-
type: first.type,
|
|
194
|
-
group: first.group,
|
|
195
|
-
};
|
|
196
|
-
var url = this.option.logServer + stringify(query);
|
|
197
|
-
if (!(!isLtIos14
|
|
198
|
-
&& navigator.sendBeacon
|
|
199
|
-
&& navigator.sendBeacon(url, JSON.stringify(data)))) {
|
|
200
|
-
this.fetch(url, data);
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
176
|
SpyClient.prototype.handle = function (logItem) {
|
|
204
177
|
if (!this.check(logItem)) {
|
|
205
178
|
return;
|
|
206
179
|
}
|
|
180
|
+
logItem = assign({
|
|
181
|
+
pid: this.option.pid,
|
|
182
|
+
lid: this.option.lid,
|
|
183
|
+
ts: Date.now(),
|
|
184
|
+
group: 'common',
|
|
185
|
+
}, logItem);
|
|
186
|
+
if (this.option.localCache) {
|
|
187
|
+
this.option.localCache.addLog(logItem);
|
|
188
|
+
}
|
|
207
189
|
// 当前api设置了抽样,
|
|
208
190
|
if (typeof logItem.sample === 'number') {
|
|
209
191
|
if (Math.random() > logItem.sample) {
|
|
@@ -213,12 +195,6 @@ var SpyClient = (function () {
|
|
|
213
195
|
else if (typeof this.option.sample === 'number' && Math.random() > this.option.sample) { // 否则,用全局抽样
|
|
214
196
|
return;
|
|
215
197
|
}
|
|
216
|
-
logItem = assign({
|
|
217
|
-
pid: this.option.pid,
|
|
218
|
-
lid: this.option.lid,
|
|
219
|
-
ts: Date.now(),
|
|
220
|
-
group: 'common',
|
|
221
|
-
}, logItem);
|
|
222
198
|
delete logItem.sample;
|
|
223
199
|
return logItem;
|
|
224
200
|
};
|
|
@@ -238,16 +214,7 @@ var SpyClient = (function () {
|
|
|
238
214
|
continue;
|
|
239
215
|
}
|
|
240
216
|
var url = this.option.logServer + stringify(logItem);
|
|
241
|
-
|
|
242
|
-
// 但是ios有些问题:在webkit浏览内核环境下,beacon requests的请求方式存在证书验证的bug,发送失败但返回正确.
|
|
243
|
-
// 修复说明在如下链接中:https://bugs.webkit.org/show_bug.cgi?id=193508
|
|
244
|
-
// 但是目前为止,在iOS12.2版本中该问题依旧存在
|
|
245
|
-
// 2021-11-11: 发现ios 14可以送,故小于14的不发送
|
|
246
|
-
if (!(!isLtIos14
|
|
247
|
-
&& navigator.sendBeacon
|
|
248
|
-
&& navigator.sendBeacon(url))) {
|
|
249
|
-
(new Image()).src = url;
|
|
250
|
-
}
|
|
217
|
+
this.request(url);
|
|
251
218
|
}
|
|
252
219
|
if (post) {
|
|
253
220
|
this.sendPost(postData);
|
|
@@ -392,6 +359,48 @@ var SpyClient = (function () {
|
|
|
392
359
|
SpyClient.prototype.clearAllMark = function () {
|
|
393
360
|
this.markCache = {};
|
|
394
361
|
};
|
|
362
|
+
// send(data, true) 也能以post发送,但是会有严格校验
|
|
363
|
+
// sendPost能以post发送,但没有校验
|
|
364
|
+
SpyClient.prototype.sendPost = function (data) {
|
|
365
|
+
var logItems = isArray(data) ? data : [data];
|
|
366
|
+
var first = logItems[0];
|
|
367
|
+
// 需要在页面暴漏出来pid等基本信息,方式调试查看基本信息与兼容目前的监控
|
|
368
|
+
var query = {
|
|
369
|
+
pid: first.pid,
|
|
370
|
+
type: first.type,
|
|
371
|
+
group: first.group,
|
|
372
|
+
};
|
|
373
|
+
var url = this.option.logServer + stringify(query);
|
|
374
|
+
this.request(url, data);
|
|
375
|
+
};
|
|
376
|
+
// 有data时,意味着要用post发送请求
|
|
377
|
+
SpyClient.prototype.request = function (url, data) {
|
|
378
|
+
if (!(!isLtIos14
|
|
379
|
+
&& navigator
|
|
380
|
+
&& navigator.sendBeacon
|
|
381
|
+
&& navigator.sendBeacon(url, data ? JSON.stringify(data) : undefined))) {
|
|
382
|
+
if (data) {
|
|
383
|
+
this.fetch(url, data);
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
(new Image()).src = url;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
SpyClient.prototype.fetch = function (url, data) {
|
|
391
|
+
if (!fetch) {
|
|
392
|
+
err('Global fetch method doesn\'t exist');
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
fetch(url, {
|
|
396
|
+
method: 'POST',
|
|
397
|
+
credentials: 'include',
|
|
398
|
+
headers: {
|
|
399
|
+
'Content-Type': 'application/json',
|
|
400
|
+
},
|
|
401
|
+
body: JSON.stringify(data),
|
|
402
|
+
});
|
|
403
|
+
};
|
|
395
404
|
return SpyClient;
|
|
396
405
|
}());
|
|
397
406
|
|
|
@@ -1365,8 +1374,25 @@ var SpyClient = (function () {
|
|
|
1365
1374
|
document.addEventListener('visibilitychange', _this.visibilitychangeCB);
|
|
1366
1375
|
window.addEventListener('beforeunload', _this.leave, false);
|
|
1367
1376
|
window.addEventListener('unload', _this.leave, false);
|
|
1377
|
+
_this.handleHead();
|
|
1368
1378
|
return _this;
|
|
1369
1379
|
}
|
|
1380
|
+
SpyClient.prototype.handleHead = function () {
|
|
1381
|
+
var _this = this;
|
|
1382
|
+
if (this.option.localCache) {
|
|
1383
|
+
var spyHead = window.__spyHead;
|
|
1384
|
+
if (spyHead && spyHead.winerrors) {
|
|
1385
|
+
for (var index = 0; index < spyHead.winerrors.length; index++) {
|
|
1386
|
+
var obj = spyHead.winerrors[index];
|
|
1387
|
+
this.option.localCache.addLog(obj);
|
|
1388
|
+
}
|
|
1389
|
+
// Head发送的异常,也保存一份到本地,主要是JS错误和资源加载异常
|
|
1390
|
+
spyHead.interceptor = function (obj) {
|
|
1391
|
+
_this.option.localCache.addLog(obj);
|
|
1392
|
+
};
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
};
|
|
1370
1396
|
SpyClient.prototype.listenFID = function (cb) {
|
|
1371
1397
|
this.invoke('listenFID', cb);
|
|
1372
1398
|
};
|