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.
Files changed (70) hide show
  1. package/README.md +9 -3
  2. package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/base.css +224 -0
  3. package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/basicSpec.ts.html +740 -0
  4. package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/block-navigation.js +79 -0
  5. package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/checkSpec.ts.html +479 -0
  6. package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/favicon.png +0 -0
  7. package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/headSpec.ts.html +695 -0
  8. package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/index.html +171 -0
  9. package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/markSpec.ts.html +284 -0
  10. package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/metricSpec.ts.html +977 -0
  11. package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/prettify.css +1 -0
  12. package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/prettify.js +2 -0
  13. package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/sort-arrow-sprite.png +0 -0
  14. package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/sorter.js +170 -0
  15. package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/base.css +224 -0
  16. package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/basicSpec.ts.html +740 -0
  17. package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/block-navigation.js +79 -0
  18. package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/checkSpec.ts.html +479 -0
  19. package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/favicon.png +0 -0
  20. package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/headSpec.ts.html +695 -0
  21. package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/index.html +171 -0
  22. package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/markSpec.ts.html +284 -0
  23. package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/metricSpec.ts.html +977 -0
  24. package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/prettify.css +1 -0
  25. package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/prettify.js +2 -0
  26. package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/sort-arrow-sprite.png +0 -0
  27. package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/sorter.js +170 -0
  28. package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/base.css +224 -0
  29. package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/basicSpec.ts.html +740 -0
  30. package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/block-navigation.js +79 -0
  31. package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/checkSpec.ts.html +479 -0
  32. package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/favicon.png +0 -0
  33. package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/headSpec.ts.html +695 -0
  34. package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/index.html +171 -0
  35. package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/markSpec.ts.html +284 -0
  36. package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/metricSpec.ts.html +977 -0
  37. package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/prettify.css +1 -0
  38. package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/prettify.js +2 -0
  39. package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/sort-arrow-sprite.png +0 -0
  40. package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/sorter.js +170 -0
  41. package/dist/head/base.d.ts +12 -7
  42. package/dist/lib/interface.d.ts +4 -0
  43. package/dist/spy-client-basic.d.ts +4 -1
  44. package/dist/spy-client-basic.esm.js +80 -21
  45. package/dist/spy-client-basic.iife.js +80 -21
  46. package/dist/spy-client-basic.iife.min.js +1 -1
  47. package/dist/spy-client-basic.js +80 -21
  48. package/dist/spy-client-basic.min.js +1 -1
  49. package/dist/spy-client-basic.mjs +80 -21
  50. package/dist/spy-client.d.ts +1 -0
  51. package/dist/spy-client.esm.js +107 -31
  52. package/dist/spy-client.iife.js +107 -31
  53. package/dist/spy-client.iife.min.js +1 -1
  54. package/dist/spy-client.js +107 -31
  55. package/dist/spy-client.min.js +1 -1
  56. package/dist/spy-client.mjs +107 -31
  57. package/dist/spy-head.js +46 -34
  58. package/dist/spy-head.min.js +1 -1
  59. package/dist/spy-local-cache.js +65 -65
  60. package/dist/spy-local-cache.min.js +1 -1
  61. package/example/local-cache.html +77 -15
  62. package/package.json +4 -12
  63. package/src/head/base.ts +37 -4
  64. package/src/head/error.ts +9 -19
  65. package/src/head/whitescreen.ts +14 -14
  66. package/src/lib/huffman.ts +37 -56
  67. package/src/lib/interface.ts +5 -0
  68. package/src/spy-client-basic.ts +92 -23
  69. package/src/spy-client.ts +19 -1
  70. package/src/spy-local-cache.ts +41 -16
@@ -33,7 +33,8 @@
33
33
  * @author kaivean
34
34
  */
35
35
  var defaultLogServer = 'https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/mwb2.gif?';
36
- var isIos = /(iPhone|iPod|iPad)/.test(navigator.userAgent);
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.send = function (query) {
69
- if (!this.check(query)) {
73
+ SpyClient.prototype.fetch = function (url, data) {
74
+ if (!window.fetch) {
70
75
  return;
71
76
  }
72
- // 当前api设置了抽样,
73
- if (typeof query.sample === 'number') {
74
- if (Math.random() > query.sample) {
75
- return;
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
- else if (typeof this.option.sample === 'number' && Math.random() > this.option.sample) { // 否则,用全局抽样
101
+ };
102
+ SpyClient.prototype.handle = function (logItem) {
103
+ if (!this.check(logItem)) {
79
104
  return;
80
105
  }
81
- query = assign({
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
- }, query);
87
- delete query.sample;
88
- var url = this.option.logServer + stringify(query);
89
- // 目前服务器端支持sendBeacon的post请求,可以优先采用,该api可以降低打点丢失率
90
- // 但是ios有些问题:在webkit浏览内核环境下,beacon requests的请求方式存在证书验证的bug.
91
- // 修复说明在如下链接中:https://bugs.webkit.org/show_bug.cgi?id=193508
92
- // 但是目前为止,在iOS12.2版本中该问题依旧存在
93
- if (!(!isIos
94
- && navigator.sendBeacon
95
- && navigator.sendBeacon(url))) {
96
- (new Image()).src = url;
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 t=/(iPhone|iPod|iPad)/.test(navigator.userAgent);function u(e){console.error("[SpyClient_log]"+e)}function e(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,logServer:e.logServer||"https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/mwb2.gif?"}}return e.prototype.send=function(e){if(this.check(e)){if("number"==typeof e.sample){if(Math.random()>e.sample)return}else if("number"==typeof this.option.sample&&Math.random()>this.option.sample)return;delete(e=o({pid:this.option.pid,lid:this.option.lid,ts:Date.now(),group:"common"},e)).sample;var n,e=this.option.logServer+(n=e,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("&"));!t&&navigator.sendBeacon&&navigator.sendBeacon(e)||((new Image).src=e)}},e.prototype.check=function(e){if(!this.option.check)return!0;var t=["perf","except","dist","count"];if(-1===t.indexOf(e.type))return u("type only is one of "+t.join(", ")),!1;if(e.group&&30<e.group.length)return u("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 u("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 u("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 u("info."+i+" value length execeeds 30 when type == 'dist'"),!1}else if("number"!=typeof s)return u("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 u("dim key ["+c+"] is unexpected. Length must be not more than 30. Supported chars: a-zA-Z0-9-_"),!1;var f=e.dim[c];if(!/^[a-zA-Z0-9\-_\*\.\s\/#\+@\&\u4e00-\u9fa5]{0,30}$/.test(f))return u("dim."+c+" value ["+f+"] is unexpected. Length must be not more than 30. Supported chars: a-zA-Z0-9-_*. /#+@& and Chinese"),!1}return!0},e.prototype.sendPerf=function(e){this.send(o({type:"perf"},e))},e.prototype.sendExcept=function(e){this.send(o({type:"except"},e))},e.prototype.sendDist=function(e){this.send(o({type:"dist"},e))},e.prototype.sendCount=function(e){this.send(o({type:"count"},e))},e.prototype.sendExceptForError=function(e,t){var n=o({},t);n.info=o({},t.info||{},{msg:e.message,stack:e.stack}),this.sendExcept(n)},e.prototype.startMark=function(e){this.markCache[e]={start:Date.now()}},e.prototype.endMark=function(e){return this.markCache[e]?(this.markCache[e].total=Date.now()-this.markCache[e].start,this.markCache[e].total):0},e.prototype.clearMark=function(e){this.markCache[e]&&delete this.markCache[e]},e.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},e.prototype.clearAllMark=function(){this.markCache={}},e});
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 isIos = /(iPhone|iPod|iPad)/.test(navigator.userAgent);
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.send = function (query) {
63
- if (!this.check(query)) {
67
+ SpyClient.prototype.fetch = function (url, data) {
68
+ if (!window.fetch) {
64
69
  return;
65
70
  }
66
- // 当前api设置了抽样,
67
- if (typeof query.sample === 'number') {
68
- if (Math.random() > query.sample) {
69
- return;
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
- else if (typeof this.option.sample === 'number' && Math.random() > this.option.sample) { // 否则,用全局抽样
95
+ };
96
+ SpyClient.prototype.handle = function (logItem) {
97
+ if (!this.check(logItem)) {
73
98
  return;
74
99
  }
75
- query = assign({
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
- }, query);
81
- delete query.sample;
82
- var url = this.option.logServer + stringify(query);
83
- // 目前服务器端支持sendBeacon的post请求,可以优先采用,该api可以降低打点丢失率
84
- // 但是ios有些问题:在webkit浏览内核环境下,beacon requests的请求方式存在证书验证的bug.
85
- // 修复说明在如下链接中:https://bugs.webkit.org/show_bug.cgi?id=193508
86
- // 但是目前为止,在iOS12.2版本中该问题依旧存在
87
- if (!(!isIos
88
- && navigator.sendBeacon
89
- && navigator.sendBeacon(url))) {
90
- (new Image()).src = url;
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) {
@@ -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;
@@ -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
- Permission to use, copy, modify, and/or distribute this software for any
5
- purpose with or without fee is hereby granted.
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
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
8
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
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 isIos = /(iPhone|iPod|iPad)/.test(navigator.userAgent);
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.send = function (query) {
168
- if (!this.check(query)) {
172
+ SpyClient.prototype.fetch = function (url, data) {
173
+ if (!window.fetch) {
169
174
  return;
170
175
  }
171
- // 当前api设置了抽样,
172
- if (typeof query.sample === 'number') {
173
- if (Math.random() > query.sample) {
174
- return;
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
- else if (typeof this.option.sample === 'number' && Math.random() > this.option.sample) { // 否则,用全局抽样
200
+ };
201
+ SpyClient.prototype.handle = function (logItem) {
202
+ if (!this.check(logItem)) {
178
203
  return;
179
204
  }
180
- query = assign({
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
- }, query);
186
- delete query.sample;
187
- var url = this.option.logServer + stringify(query);
188
- // 目前服务器端支持sendBeacon的post请求,可以优先采用,该api可以降低打点丢失率
189
- // 但是ios有些问题:在webkit浏览内核环境下,beacon requests的请求方式存在证书验证的bug.
190
- // 修复说明在如下链接中:https://bugs.webkit.org/show_bug.cgi?id=193508
191
- // 但是目前为止,在iOS12.2版本中该问题依旧存在
192
- if (!(!isIos
193
- && navigator.sendBeacon
194
- && navigator.sendBeacon(url))) {
195
- (new Image()).src = url;
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
  };