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/src/spy-client-basic.ts
CHANGED
|
@@ -69,7 +69,9 @@ interface ErrorOption {
|
|
|
69
69
|
|
|
70
70
|
const defaultLogServer = 'https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/mwb2.gif?';
|
|
71
71
|
|
|
72
|
-
const
|
|
72
|
+
const ver = navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?)_/);
|
|
73
|
+
const isLtIos14 = ver && ver[2] && (+ver[2] < 14);
|
|
74
|
+
|
|
73
75
|
|
|
74
76
|
function err(msg: string) {
|
|
75
77
|
console.error(`[SpyClient_log]${msg}`);
|
|
@@ -91,6 +93,10 @@ function stringify(obj: any) {
|
|
|
91
93
|
}).join('&');
|
|
92
94
|
}
|
|
93
95
|
|
|
96
|
+
function isArray(arr: any) {
|
|
97
|
+
return Object.prototype.toString.call(arr) === '[object Array]';
|
|
98
|
+
}
|
|
99
|
+
|
|
94
100
|
interface SpyClientInnerOption extends SpyClientOption {
|
|
95
101
|
logServer: string;
|
|
96
102
|
}
|
|
@@ -113,49 +119,112 @@ export default class SpyClient {
|
|
|
113
119
|
lid: option.lid,
|
|
114
120
|
check: option.check !== false,
|
|
115
121
|
sample: option.sample,
|
|
122
|
+
localCache: option.localCache,
|
|
116
123
|
logServer: option.logServer || defaultLogServer,
|
|
117
124
|
};
|
|
118
125
|
}
|
|
119
126
|
|
|
120
|
-
|
|
121
|
-
if (!
|
|
127
|
+
fetch(url: string, data: any) {
|
|
128
|
+
if (!window.fetch) {
|
|
122
129
|
return;
|
|
123
130
|
}
|
|
131
|
+
fetch(url, {
|
|
132
|
+
method: 'POST',
|
|
133
|
+
credentials: 'include',
|
|
134
|
+
headers: {
|
|
135
|
+
'Content-Type': 'application/json',
|
|
136
|
+
},
|
|
137
|
+
body: JSON.stringify(data),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
124
140
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
141
|
+
sendPost(data: any) {
|
|
142
|
+
let logItems: any[] = isArray(data) ? data : [data];
|
|
143
|
+
const first = logItems[0];
|
|
144
|
+
// 需要在页面暴漏出来pid等基本信息,方式调试查看基本信息与兼容目前的监控
|
|
145
|
+
const query = {
|
|
146
|
+
pid: first.pid,
|
|
147
|
+
type: first.type,
|
|
148
|
+
group: first.group,
|
|
149
|
+
};
|
|
150
|
+
const url = this.option.logServer + stringify(query);
|
|
151
|
+
|
|
152
|
+
if (!(
|
|
153
|
+
!isLtIos14
|
|
154
|
+
&& navigator.sendBeacon
|
|
155
|
+
&& navigator.sendBeacon(url, JSON.stringify(data))
|
|
156
|
+
)) {
|
|
157
|
+
this.fetch(url, data);
|
|
130
158
|
}
|
|
131
|
-
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
handle(logItem: any) {
|
|
162
|
+
if (!this.check(logItem)) {
|
|
132
163
|
return;
|
|
133
164
|
}
|
|
134
165
|
|
|
135
|
-
|
|
166
|
+
logItem = assign(
|
|
136
167
|
{
|
|
137
168
|
pid: this.option.pid,
|
|
138
169
|
lid: this.option.lid,
|
|
139
170
|
ts: Date.now(),
|
|
140
171
|
group: 'common',
|
|
141
172
|
},
|
|
142
|
-
|
|
173
|
+
logItem
|
|
143
174
|
);
|
|
144
175
|
|
|
145
|
-
|
|
176
|
+
if (this.option.localCache) {
|
|
177
|
+
this.option.localCache.addLog(logItem);
|
|
178
|
+
}
|
|
146
179
|
|
|
147
|
-
|
|
180
|
+
// 当前api设置了抽样,
|
|
181
|
+
if (typeof logItem.sample === 'number') {
|
|
182
|
+
if (Math.random() > logItem.sample) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else if (typeof this.option.sample === 'number' && Math.random() > this.option.sample) { // 否则,用全局抽样
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
148
189
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
)
|
|
158
|
-
|
|
190
|
+
delete logItem.sample;
|
|
191
|
+
return logItem;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
send(data: any, post = false) {
|
|
195
|
+
let logItems: any[] = isArray(data) ? data : [data];
|
|
196
|
+
|
|
197
|
+
let postData = [];
|
|
198
|
+
for (let logItem of logItems) {
|
|
199
|
+
logItem = this.handle(logItem);
|
|
200
|
+
if (!logItem) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
postData.push(logItem);
|
|
205
|
+
|
|
206
|
+
// 期望通过post方式上传日志
|
|
207
|
+
if (post) {
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const url = this.option.logServer + stringify(logItem);
|
|
212
|
+
|
|
213
|
+
// 目前服务器端支持sendBeacon的post请求,可以优先采用,该api可以降低打点丢失率
|
|
214
|
+
// 但是ios有些问题:在webkit浏览内核环境下,beacon requests的请求方式存在证书验证的bug,发送失败但返回正确.
|
|
215
|
+
// 修复说明在如下链接中:https://bugs.webkit.org/show_bug.cgi?id=193508
|
|
216
|
+
// 但是目前为止,在iOS12.2版本中该问题依旧存在
|
|
217
|
+
// 2021-11-11: 发现ios 14可以送,故小于14的不发送
|
|
218
|
+
if (!(
|
|
219
|
+
!isLtIos14
|
|
220
|
+
&& navigator.sendBeacon
|
|
221
|
+
&& navigator.sendBeacon(url)
|
|
222
|
+
)) {
|
|
223
|
+
(new Image()).src = url;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (post) {
|
|
227
|
+
this.sendPost(postData);
|
|
159
228
|
}
|
|
160
229
|
}
|
|
161
230
|
|
package/src/spy-client.ts
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
ResOption,
|
|
28
28
|
BigImgOption,
|
|
29
29
|
HttpResOption,
|
|
30
|
-
SlowOption
|
|
30
|
+
SlowOption,
|
|
31
31
|
} from './lib/interface';
|
|
32
32
|
|
|
33
33
|
import FID from './module/fid';
|
|
@@ -70,6 +70,24 @@ export default class SpyClient extends SpyClientBasic {
|
|
|
70
70
|
document.addEventListener('visibilitychange', this.visibilitychangeCB);
|
|
71
71
|
window.addEventListener('beforeunload', this.leave, false);
|
|
72
72
|
window.addEventListener('unload', this.leave, false);
|
|
73
|
+
|
|
74
|
+
this.handleHead();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
handleHead() {
|
|
78
|
+
if (this.option.localCache) {
|
|
79
|
+
const spyHead = window.__spyHead;
|
|
80
|
+
if (spyHead && spyHead.winerrors) {
|
|
81
|
+
for (let index = 0; index < spyHead.winerrors.length; index++) {
|
|
82
|
+
const obj = spyHead.winerrors[index];
|
|
83
|
+
this.option.localCache.addLog(obj);
|
|
84
|
+
}
|
|
85
|
+
// Head发送的异常,也保存一份到本地,主要是JS错误和资源加载异常
|
|
86
|
+
spyHead.interceptor = (obj: any) => {
|
|
87
|
+
this.option.localCache.addLog(obj);
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
73
91
|
}
|
|
74
92
|
|
|
75
93
|
listenFID(cb: FIDCB) {
|
package/src/spy-local-cache.ts
CHANGED
|
@@ -6,9 +6,10 @@ interface Option {
|
|
|
6
6
|
key: string;
|
|
7
7
|
maxRecordLen: number;
|
|
8
8
|
interval: number;
|
|
9
|
-
onFlush
|
|
9
|
+
onFlush?: (res: any) => void;
|
|
10
|
+
onSave?: (res: any) => void;
|
|
11
|
+
onAdd?: (res: any) => boolean;
|
|
10
12
|
storage: 'indexedDB' | 'localstorage' | 'empty';
|
|
11
|
-
costTime?: (time: string) => void;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
class Storage {
|
|
@@ -280,6 +281,10 @@ export default class SpyLocalCache {
|
|
|
280
281
|
interval: 500,
|
|
281
282
|
maxRecordLen: 30,
|
|
282
283
|
onFlush: () => {},
|
|
284
|
+
onSave: () => {},
|
|
285
|
+
onAdd: () => {
|
|
286
|
+
return true;
|
|
287
|
+
},
|
|
283
288
|
storage: IndexedDB.isSupport()
|
|
284
289
|
? 'indexedDB'
|
|
285
290
|
: LS.isSupport()
|
|
@@ -318,6 +323,12 @@ export default class SpyLocalCache {
|
|
|
318
323
|
}
|
|
319
324
|
|
|
320
325
|
addLog(info: any) {
|
|
326
|
+
if (this.option.onAdd) {
|
|
327
|
+
if (!this.option.onAdd(info)) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
321
332
|
info = JSON.stringify(info);
|
|
322
333
|
|
|
323
334
|
this.tmpList.push(info as string);
|
|
@@ -363,28 +374,42 @@ export default class SpyLocalCache {
|
|
|
363
374
|
}
|
|
364
375
|
|
|
365
376
|
save() {
|
|
377
|
+
const st = Date.now();
|
|
366
378
|
this.getData((list: any[]) => {
|
|
367
379
|
// 只保留最近的maxRecordLen条日志
|
|
368
380
|
const reserveLen = this.option.maxRecordLen - 1;
|
|
369
381
|
const originList = list.length > reserveLen ? list.slice(list.length - reserveLen, list.length) : list;
|
|
370
|
-
let
|
|
371
|
-
let
|
|
372
|
-
let
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
this.
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
382
|
+
let newList = originList.concat(this.tmpList);
|
|
383
|
+
let content = newList.join('\n');
|
|
384
|
+
let error: Error | null = null;
|
|
385
|
+
let len = 0;
|
|
386
|
+
try {
|
|
387
|
+
let data = this.zip(content);
|
|
388
|
+
let codesStr = '';
|
|
389
|
+
if (data.codes) {
|
|
390
|
+
codesStr = JSON.stringify(data.codes);
|
|
391
|
+
this.storage.set(this.option.key + 'Codes', codesStr);
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
this.storage.rm(this.option.key + 'Codes');
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
this.storage.set(this.option.key, data.result);
|
|
398
|
+
len = data.result.length;
|
|
379
399
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
if (this.option.costTime) {
|
|
384
|
-
this.option.costTime(costTime);
|
|
400
|
+
catch (e) {
|
|
401
|
+
error = e;
|
|
402
|
+
console.error(e);
|
|
385
403
|
}
|
|
386
404
|
|
|
387
405
|
this.tmpList = [];
|
|
406
|
+
|
|
407
|
+
this.option.onSave && this.option.onSave({
|
|
408
|
+
cost: Date.now() - st,
|
|
409
|
+
length: len / 1024,
|
|
410
|
+
list: newList,
|
|
411
|
+
error: error,
|
|
412
|
+
});
|
|
388
413
|
});
|
|
389
414
|
}
|
|
390
415
|
|