@whitesev/utils 1.5.6 → 1.5.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.
@@ -5,28 +5,45 @@
5
5
  // @updateLog xhr事件增加currentTarget劫持。
6
6
  // @supportURL https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
7
7
 
8
- const AjaxHooker = function () {
9
- return function() {
10
- 'use strict';
11
- const version = '1.4.3';
8
+ export const AjaxHooker = function () {
9
+ return (function () {
10
+ "use strict";
11
+ const version = "1.4.3";
12
12
  const hookInst = {
13
13
  hookFns: [],
14
- filters: []
14
+ filters: [],
15
15
  };
16
16
  const win = window.unsafeWindow || document.defaultView || window;
17
17
  let winAh = win.__ajaxHooker;
18
18
  const resProto = win.Response.prototype;
19
- const xhrResponses = ['response', 'responseText', 'responseXML'];
20
- const fetchResponses = ['arrayBuffer', 'blob', 'formData', 'json', 'text'];
21
- const fetchInitProps = ['method', 'headers', 'body', 'mode', 'credentials', 'cache', 'redirect',
22
- 'referrer', 'referrerPolicy', 'integrity', 'keepalive', 'signal', 'priority'];
23
- const xhrAsyncEvents = ['readystatechange', 'load', 'loadend'];
24
- const getType = ({}).toString.call.bind(({}).toString);
19
+ const xhrResponses = ["response", "responseText", "responseXML"];
20
+ const fetchResponses = ["arrayBuffer", "blob", "formData", "json", "text"];
21
+ const fetchInitProps = [
22
+ "method",
23
+ "headers",
24
+ "body",
25
+ "mode",
26
+ "credentials",
27
+ "cache",
28
+ "redirect",
29
+ "referrer",
30
+ "referrerPolicy",
31
+ "integrity",
32
+ "keepalive",
33
+ "signal",
34
+ "priority",
35
+ ];
36
+ const xhrAsyncEvents = ["readystatechange", "load", "loadend"];
37
+ const getType = {}.toString.call.bind({}.toString);
25
38
  const getDescriptor = Object.getOwnPropertyDescriptor.bind(Object);
26
39
  const emptyFn = () => {};
27
- const errorFn = e => console.error(e);
40
+ const errorFn = (e) => console.error(e);
28
41
  function isThenable(obj) {
29
- return obj && ['object', 'function'].includes(typeof obj) && typeof obj.then === 'function';
42
+ return (
43
+ obj &&
44
+ ["object", "function"].includes(typeof obj) &&
45
+ typeof obj.then === "function"
46
+ );
30
47
  }
31
48
  function catchError(fn, ...args) {
32
49
  try {
@@ -42,7 +59,7 @@ const AjaxHooker = function () {
42
59
  configurable: true,
43
60
  enumerable: true,
44
61
  get: getter,
45
- set: setter
62
+ set: setter,
46
63
  });
47
64
  }
48
65
  function readonly(obj, prop, value = obj[prop]) {
@@ -53,27 +70,28 @@ const AjaxHooker = function () {
53
70
  configurable: true,
54
71
  enumerable: true,
55
72
  writable: true,
56
- value: value
73
+ value: value,
57
74
  });
58
75
  }
59
76
  function parseHeaders(obj) {
60
77
  const headers = {};
61
78
  switch (getType(obj)) {
62
- case '[object String]':
79
+ case "[object String]":
63
80
  for (const line of obj.trim().split(/[\r\n]+/)) {
64
81
  const [header, value] = line.split(/\s*:\s*/);
65
82
  if (!header) break;
66
83
  const lheader = header.toLowerCase();
67
- headers[lheader] = lheader in headers ? `${headers[lheader]}, ${value}` : value;
84
+ headers[lheader] =
85
+ lheader in headers ? `${headers[lheader]}, ${value}` : value;
68
86
  }
69
87
  break;
70
- case '[object Headers]':
88
+ case "[object Headers]":
71
89
  for (const [key, val] of obj) {
72
90
  headers[key] = val;
73
91
  }
74
92
  break;
75
- case '[object Object]':
76
- return {...obj};
93
+ case "[object Object]":
94
+ return { ...obj };
77
95
  }
78
96
  return headers;
79
97
  }
@@ -89,104 +107,142 @@ const AjaxHooker = function () {
89
107
  class AHRequest {
90
108
  constructor(request) {
91
109
  this.request = request;
92
- this.requestClone = {...this.request};
110
+ this.requestClone = { ...this.request };
93
111
  }
94
112
  shouldFilter(filters) {
95
- const {type, url, method, async} = this.request;
96
- return filters.length && !filters.find(obj => {
97
- switch (true) {
98
- case obj.type && obj.type !== type:
99
- case getType(obj.url) === '[object String]' && !url.includes(obj.url):
100
- case getType(obj.url) === '[object RegExp]' && !obj.url.test(url):
101
- case obj.method && obj.method.toUpperCase() !== method.toUpperCase():
102
- case 'async' in obj && obj.async !== async:
103
- return false;
104
- }
105
- return true;
106
- });
113
+ const { type, url, method, async } = this.request;
114
+ return (
115
+ filters.length &&
116
+ !filters.find((obj) => {
117
+ switch (true) {
118
+ case obj.type && obj.type !== type:
119
+ case getType(obj.url) === "[object String]" &&
120
+ !url.includes(obj.url):
121
+ case getType(obj.url) === "[object RegExp]" && !obj.url.test(url):
122
+ case obj.method &&
123
+ obj.method.toUpperCase() !== method.toUpperCase():
124
+ case "async" in obj && obj.async !== async:
125
+ return false;
126
+ }
127
+ return true;
128
+ })
129
+ );
107
130
  }
108
131
  waitForRequestKeys() {
109
- const requestKeys = ['url', 'method', 'abort', 'headers', 'data'];
132
+ const requestKeys = ["url", "method", "abort", "headers", "data"];
110
133
  if (!this.request.async) {
111
- win.__ajaxHooker.hookInsts.forEach(({hookFns, filters}) => {
134
+ win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
112
135
  if (this.shouldFilter(filters)) return;
113
- hookFns.forEach(fn => {
114
- if (getType(fn) === '[object Function]') catchError(fn, this.request);
136
+ hookFns.forEach((fn) => {
137
+ if (getType(fn) === "[object Function]")
138
+ catchError(fn, this.request);
115
139
  });
116
- requestKeys.forEach(key => {
117
- if (isThenable(this.request[key])) this.request[key] = this.requestClone[key];
140
+ requestKeys.forEach((key) => {
141
+ if (isThenable(this.request[key]))
142
+ this.request[key] = this.requestClone[key];
118
143
  });
119
144
  });
120
145
  return new SyncThenable();
121
146
  }
122
147
  const promises = [];
123
- win.__ajaxHooker.hookInsts.forEach(({hookFns, filters}) => {
148
+ win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
124
149
  if (this.shouldFilter(filters)) return;
125
- promises.push(Promise.all(hookFns.map(fn => catchError(fn, this.request))).then(() =>
126
- Promise.all(requestKeys.map(key => Promise.resolve(this.request[key]).then(
127
- val => this.request[key] = val,
128
- () => this.request[key] = this.requestClone[key]
129
- )))
130
- ));
150
+ promises.push(
151
+ Promise.all(hookFns.map((fn) => catchError(fn, this.request))).then(
152
+ () =>
153
+ Promise.all(
154
+ requestKeys.map((key) =>
155
+ Promise.resolve(this.request[key]).then(
156
+ (val) => (this.request[key] = val),
157
+ () => (this.request[key] = this.requestClone[key])
158
+ )
159
+ )
160
+ )
161
+ )
162
+ );
131
163
  });
132
164
  return Promise.all(promises);
133
165
  }
134
166
  waitForResponseKeys(response) {
135
- const responseKeys = this.request.type === 'xhr' ? xhrResponses : fetchResponses;
167
+ const responseKeys =
168
+ this.request.type === "xhr" ? xhrResponses : fetchResponses;
136
169
  if (!this.request.async) {
137
- if (getType(this.request.response) === '[object Function]') {
170
+ if (getType(this.request.response) === "[object Function]") {
138
171
  catchError(this.request.response, response);
139
- responseKeys.forEach(key => {
140
- if ('get' in getDescriptor(response, key) || isThenable(response[key])) {
172
+ responseKeys.forEach((key) => {
173
+ if (
174
+ "get" in getDescriptor(response, key) ||
175
+ isThenable(response[key])
176
+ ) {
141
177
  delete response[key];
142
178
  }
143
179
  });
144
180
  }
145
181
  return new SyncThenable();
146
182
  }
147
- return Promise.resolve(catchError(this.request.response, response)).then(() =>
148
- Promise.all(responseKeys.map(key => {
149
- const descriptor = getDescriptor(response, key);
150
- if (descriptor && 'value' in descriptor) {
151
- return Promise.resolve(descriptor.value).then(
152
- val => response[key] = val,
153
- () => delete response[key]
154
- );
155
- } else {
156
- delete response[key];
157
- }
158
- }))
183
+ return Promise.resolve(
184
+ catchError(this.request.response, response)
185
+ ).then(() =>
186
+ Promise.all(
187
+ responseKeys.map((key) => {
188
+ const descriptor = getDescriptor(response, key);
189
+ if (descriptor && "value" in descriptor) {
190
+ return Promise.resolve(descriptor.value).then(
191
+ (val) => (response[key] = val),
192
+ () => delete response[key]
193
+ );
194
+ } else {
195
+ delete response[key];
196
+ }
197
+ })
198
+ )
159
199
  );
160
200
  }
161
201
  }
162
202
  const proxyHandler = {
163
203
  get(target, prop) {
164
204
  const descriptor = getDescriptor(target, prop);
165
- if (descriptor && !descriptor.configurable && !descriptor.writable && !descriptor.get) return target[prop];
205
+ if (
206
+ descriptor &&
207
+ !descriptor.configurable &&
208
+ !descriptor.writable &&
209
+ !descriptor.get
210
+ )
211
+ return target[prop];
166
212
  const ah = target.__ajaxHooker;
167
213
  if (ah && ah.proxyProps) {
168
214
  if (prop in ah.proxyProps) {
169
215
  const pDescriptor = ah.proxyProps[prop];
170
- if ('get' in pDescriptor) return pDescriptor.get();
171
- if (typeof pDescriptor.value === 'function') return pDescriptor.value.bind(ah);
216
+ if ("get" in pDescriptor) return pDescriptor.get();
217
+ if (typeof pDescriptor.value === "function")
218
+ return pDescriptor.value.bind(ah);
172
219
  return pDescriptor.value;
173
220
  }
174
- if (typeof target[prop] === 'function') return target[prop].bind(target);
221
+ if (typeof target[prop] === "function")
222
+ return target[prop].bind(target);
175
223
  }
176
224
  return target[prop];
177
225
  },
178
226
  set(target, prop, value) {
179
227
  const descriptor = getDescriptor(target, prop);
180
- if (descriptor && !descriptor.configurable && !descriptor.writable && !descriptor.set) return true;
228
+ if (
229
+ descriptor &&
230
+ !descriptor.configurable &&
231
+ !descriptor.writable &&
232
+ !descriptor.set
233
+ )
234
+ return true;
181
235
  const ah = target.__ajaxHooker;
182
236
  if (ah && ah.proxyProps && prop in ah.proxyProps) {
183
237
  const pDescriptor = ah.proxyProps[prop];
184
- pDescriptor.set ? pDescriptor.set(value) : (pDescriptor.value = value);
238
+ pDescriptor.set
239
+ ? pDescriptor.set(value)
240
+ : (pDescriptor.value = value);
185
241
  } else {
186
242
  target[prop] = value;
187
243
  }
188
244
  return true;
189
- }
245
+ },
190
246
  };
191
247
  class XhrHooker {
192
248
  constructor(xhr) {
@@ -196,86 +252,113 @@ const AjaxHooker = function () {
196
252
  proxyXhr: new Proxy(xhr, proxyHandler),
197
253
  resThenable: new SyncThenable(),
198
254
  proxyProps: {},
199
- proxyEvents: {}
255
+ proxyEvents: {},
200
256
  });
201
- xhr.addEventListener('readystatechange', e => {
202
- if (ah.proxyXhr.readyState === 4 && ah.request && typeof ah.request.response === 'function') {
257
+ xhr.addEventListener("readystatechange", (e) => {
258
+ if (
259
+ ah.proxyXhr.readyState === 4 &&
260
+ ah.request &&
261
+ typeof ah.request.response === "function"
262
+ ) {
203
263
  const response = {
204
264
  finalUrl: ah.proxyXhr.responseURL,
205
265
  status: ah.proxyXhr.status,
206
- responseHeaders: parseHeaders(ah.proxyXhr.getAllResponseHeaders())
266
+ responseHeaders: parseHeaders(
267
+ ah.proxyXhr.getAllResponseHeaders()
268
+ ),
207
269
  };
208
270
  const tempValues = {};
209
271
  for (const key of xhrResponses) {
210
272
  try {
211
273
  tempValues[key] = ah.originalXhr[key];
212
274
  } catch (err) {}
213
- defineProp(response, key, () => {
214
- return response[key] = tempValues[key];
215
- }, val => {
216
- delete response[key];
217
- response[key] = val;
218
- });
275
+ defineProp(
276
+ response,
277
+ key,
278
+ () => {
279
+ return (response[key] = tempValues[key]);
280
+ },
281
+ (val) => {
282
+ delete response[key];
283
+ response[key] = val;
284
+ }
285
+ );
219
286
  }
220
- ah.resThenable = new AHRequest(ah.request).waitForResponseKeys(response).then(() => {
221
- for (const key of xhrResponses) {
222
- ah.proxyProps[key] = {get: () => {
223
- if (!(key in response)) response[key] = tempValues[key];
224
- return response[key];
225
- }};
226
- }
227
- });
287
+ ah.resThenable = new AHRequest(ah.request)
288
+ .waitForResponseKeys(response)
289
+ .then(() => {
290
+ for (const key of xhrResponses) {
291
+ ah.proxyProps[key] = {
292
+ get: () => {
293
+ if (!(key in response)) response[key] = tempValues[key];
294
+ return response[key];
295
+ },
296
+ };
297
+ }
298
+ });
228
299
  }
229
300
  ah.dispatchEvent(e);
230
301
  });
231
- xhr.addEventListener('load', e => ah.dispatchEvent(e));
232
- xhr.addEventListener('loadend', e => ah.dispatchEvent(e));
302
+ xhr.addEventListener("load", (e) => ah.dispatchEvent(e));
303
+ xhr.addEventListener("loadend", (e) => ah.dispatchEvent(e));
233
304
  for (const evt of xhrAsyncEvents) {
234
- const onEvt = 'on' + evt;
305
+ const onEvt = "on" + evt;
235
306
  ah.proxyProps[onEvt] = {
236
307
  get: () => ah.proxyEvents[onEvt] || null,
237
- set: val => ah.addEvent(onEvt, val)
308
+ set: (val) => ah.addEvent(onEvt, val),
238
309
  };
239
310
  }
240
- for (const method of ['setRequestHeader', 'addEventListener', 'removeEventListener', 'open', 'send']) {
241
- ah.proxyProps[method] = {value: ah[method]};
311
+ for (const method of [
312
+ "setRequestHeader",
313
+ "addEventListener",
314
+ "removeEventListener",
315
+ "open",
316
+ "send",
317
+ ]) {
318
+ ah.proxyProps[method] = { value: ah[method] };
242
319
  }
243
320
  }
244
321
  toJSON() {} // Converting circular structure to JSON
245
322
  addEvent(type, event) {
246
- if (type.startsWith('on')) {
247
- this.proxyEvents[type] = typeof event === 'function' ? event : null;
323
+ if (type.startsWith("on")) {
324
+ this.proxyEvents[type] = typeof event === "function" ? event : null;
248
325
  } else {
249
- if (typeof event === 'object' && event !== null) event = event.handleEvent;
250
- if (typeof event !== 'function') return;
326
+ if (typeof event === "object" && event !== null)
327
+ event = event.handleEvent;
328
+ if (typeof event !== "function") return;
251
329
  this.proxyEvents[type] = this.proxyEvents[type] || new Set();
252
330
  this.proxyEvents[type].add(event);
253
331
  }
254
332
  }
255
333
  removeEvent(type, event) {
256
- if (type.startsWith('on')) {
334
+ if (type.startsWith("on")) {
257
335
  this.proxyEvents[type] = null;
258
336
  } else {
259
- if (typeof event === 'object' && event !== null) event = event.handleEvent;
337
+ if (typeof event === "object" && event !== null)
338
+ event = event.handleEvent;
260
339
  this.proxyEvents[type] && this.proxyEvents[type].delete(event);
261
340
  }
262
341
  }
263
342
  dispatchEvent(e) {
264
343
  e.stopImmediatePropagation = stopImmediatePropagation;
265
- defineProp(e, 'target', () => this.proxyXhr);
266
- defineProp(e, 'currentTarget', () => this.proxyXhr);
267
- this.proxyEvents[e.type] && this.proxyEvents[e.type].forEach(fn => {
268
- this.resThenable.then(() => !e.ajaxHooker_isStopped && fn.call(this.proxyXhr, e));
269
- });
344
+ defineProp(e, "target", () => this.proxyXhr);
345
+ defineProp(e, "currentTarget", () => this.proxyXhr);
346
+ this.proxyEvents[e.type] &&
347
+ this.proxyEvents[e.type].forEach((fn) => {
348
+ this.resThenable.then(
349
+ () => !e.ajaxHooker_isStopped && fn.call(this.proxyXhr, e)
350
+ );
351
+ });
270
352
  if (e.ajaxHooker_isStopped) return;
271
- const onEvent = this.proxyEvents['on' + e.type];
353
+ const onEvent = this.proxyEvents["on" + e.type];
272
354
  onEvent && this.resThenable.then(onEvent.bind(this.proxyXhr, e));
273
355
  }
274
356
  setRequestHeader(header, value) {
275
357
  this.originalXhr.setRequestHeader(header, value);
276
358
  if (!this.request) return;
277
359
  const headers = this.request.headers;
278
- headers[header] = header in headers ? `${headers[header]}, ${value}` : value;
360
+ headers[header] =
361
+ header in headers ? `${headers[header]}, ${value}` : value;
279
362
  }
280
363
  addEventListener(...args) {
281
364
  if (xhrAsyncEvents.includes(args[0])) {
@@ -293,18 +376,24 @@ const AjaxHooker = function () {
293
376
  }
294
377
  open(method, url, async = true, ...args) {
295
378
  this.request = {
296
- type: 'xhr',
379
+ type: "xhr",
297
380
  url: url.toString(),
298
381
  method: method.toUpperCase(),
299
382
  abort: false,
300
383
  headers: {},
301
384
  data: null,
302
385
  response: null,
303
- async: !!async
386
+ async: !!async,
304
387
  };
305
388
  this.openArgs = args;
306
389
  this.resThenable = new SyncThenable();
307
- ['responseURL', 'readyState', 'status', 'statusText', ...xhrResponses].forEach(key => {
390
+ [
391
+ "responseURL",
392
+ "readyState",
393
+ "status",
394
+ "statusText",
395
+ ...xhrResponses,
396
+ ].forEach((key) => {
308
397
  delete this.proxyProps[key];
309
398
  });
310
399
  return this.originalXhr.open(method, url, async, ...args);
@@ -317,17 +406,24 @@ const AjaxHooker = function () {
317
406
  request.data = data;
318
407
  new AHRequest(request).waitForRequestKeys().then(() => {
319
408
  if (request.abort) {
320
- if (typeof request.response === 'function') {
409
+ if (typeof request.response === "function") {
321
410
  Object.assign(ah.proxyProps, {
322
- responseURL: {value: request.url},
323
- readyState: {value: 4},
324
- status: {value: 200},
325
- statusText: {value: 'OK'}
411
+ responseURL: { value: request.url },
412
+ readyState: { value: 4 },
413
+ status: { value: 200 },
414
+ statusText: { value: "OK" },
326
415
  });
327
- xhrAsyncEvents.forEach(evt => xhr.dispatchEvent(new Event(evt)));
416
+ xhrAsyncEvents.forEach((evt) =>
417
+ xhr.dispatchEvent(new Event(evt))
418
+ );
328
419
  }
329
420
  } else {
330
- xhr.open(request.method, request.url, request.async, ...ah.openArgs);
421
+ xhr.open(
422
+ request.method,
423
+ request.url,
424
+ request.async,
425
+ ...ah.openArgs
426
+ );
331
427
  for (const header in request.headers) {
332
428
  xhr.setRequestHeader(header, request.headers[header]);
333
429
  }
@@ -338,79 +434,87 @@ const AjaxHooker = function () {
338
434
  }
339
435
  function fakeXHR() {
340
436
  const xhr = new winAh.realXHR();
341
- if ('__ajaxHooker' in xhr) console.warn('检测到不同版本的ajaxHooker,可能发生冲突!');
437
+ if ("__ajaxHooker" in xhr)
438
+ console.warn("检测到不同版本的ajaxHooker,可能发生冲突!");
342
439
  xhr.__ajaxHooker = new XhrHooker(xhr);
343
440
  return xhr.__ajaxHooker.proxyXhr;
344
441
  }
345
442
  fakeXHR.prototype = win.XMLHttpRequest.prototype;
346
- Object.keys(win.XMLHttpRequest).forEach(key => fakeXHR[key] = win.XMLHttpRequest[key]);
443
+ Object.keys(win.XMLHttpRequest).forEach(
444
+ (key) => (fakeXHR[key] = win.XMLHttpRequest[key])
445
+ );
347
446
  function fakeFetch(url, options = {}) {
348
447
  if (!url) return winAh.realFetch.call(win, url, options);
349
448
  return new Promise(async (resolve, reject) => {
350
449
  const init = {};
351
- if (getType(url) === '[object Request]') {
450
+ if (getType(url) === "[object Request]") {
352
451
  for (const prop of fetchInitProps) init[prop] = url[prop];
353
452
  if (url.body) init.body = await url.arrayBuffer();
354
453
  url = url.url;
355
454
  }
356
455
  url = url.toString();
357
456
  Object.assign(init, options);
358
- init.method = init.method || 'GET';
457
+ init.method = init.method || "GET";
359
458
  init.headers = init.headers || {};
360
459
  const request = {
361
- type: 'fetch',
460
+ type: "fetch",
362
461
  url: url,
363
462
  method: init.method.toUpperCase(),
364
463
  abort: false,
365
464
  headers: parseHeaders(init.headers),
366
465
  data: init.body,
367
466
  response: null,
368
- async: true
467
+ async: true,
369
468
  };
370
469
  const req = new AHRequest(request);
371
470
  await req.waitForRequestKeys();
372
471
  if (request.abort) {
373
- if (typeof request.response === 'function') {
472
+ if (typeof request.response === "function") {
374
473
  const response = {
375
474
  finalUrl: request.url,
376
475
  status: 200,
377
- responseHeaders: {}
476
+ responseHeaders: {},
378
477
  };
379
478
  await req.waitForResponseKeys(response);
380
- const key = fetchResponses.find(k => k in response);
479
+ const key = fetchResponses.find((k) => k in response);
381
480
  let val = response[key];
382
- if (key === 'json' && typeof val === 'object') {
481
+ if (key === "json" && typeof val === "object") {
383
482
  val = catchError(JSON.stringify.bind(JSON), val);
384
483
  }
385
484
  const res = new Response(val, {
386
485
  status: 200,
387
- statusText: 'OK'
486
+ statusText: "OK",
388
487
  });
389
- defineProp(res, 'type', () => 'basic');
390
- defineProp(res, 'url', () => request.url);
488
+ defineProp(res, "type", () => "basic");
489
+ defineProp(res, "url", () => request.url);
391
490
  resolve(res);
392
491
  } else {
393
- reject(new DOMException('aborted', 'AbortError'));
492
+ reject(new DOMException("aborted", "AbortError"));
394
493
  }
395
494
  return;
396
495
  }
397
496
  init.method = request.method;
398
497
  init.headers = request.headers;
399
498
  init.body = request.data;
400
- winAh.realFetch.call(win, request.url, init).then(res => {
401
- if (typeof request.response === 'function') {
499
+ winAh.realFetch.call(win, request.url, init).then((res) => {
500
+ if (typeof request.response === "function") {
402
501
  const response = {
403
502
  finalUrl: res.url,
404
503
  status: res.status,
405
- responseHeaders: parseHeaders(res.headers)
504
+ responseHeaders: parseHeaders(res.headers),
406
505
  };
407
- fetchResponses.forEach(key => res[key] = function() {
408
- if (key in response) return Promise.resolve(response[key]);
409
- return resProto[key].call(this).then(val => {
410
- response[key] = val;
411
- return req.waitForResponseKeys(response).then(() => key in response ? response[key] : val);
412
- });
413
- });
506
+ fetchResponses.forEach(
507
+ (key) =>
508
+ (res[key] = function () {
509
+ if (key in response) return Promise.resolve(response[key]);
510
+ return resProto[key].call(this).then((val) => {
511
+ response[key] = val;
512
+ return req
513
+ .waitForResponseKeys(response)
514
+ .then(() => (key in response ? response[key] : val));
515
+ });
516
+ })
517
+ );
414
518
  }
415
519
  resolve(res);
416
520
  }, reject);
@@ -423,38 +527,40 @@ const AjaxHooker = function () {
423
527
  return res;
424
528
  }
425
529
  winAh = win.__ajaxHooker = winAh || {
426
- version, fakeXHR, fakeFetch, fakeFetchClone,
530
+ version,
531
+ fakeXHR,
532
+ fakeFetch,
533
+ fakeFetchClone,
427
534
  realXHR: win.XMLHttpRequest,
428
535
  realFetch: win.fetch,
429
536
  realFetchClone: resProto.clone,
430
- hookInsts: new Set()
537
+ hookInsts: new Set(),
431
538
  };
432
- if (winAh.version !== version) console.warn('检测到不同版本的ajaxHooker,可能发生冲突!');
539
+ if (winAh.version !== version)
540
+ console.warn("检测到不同版本的ajaxHooker,可能发生冲突!");
433
541
  win.XMLHttpRequest = winAh.fakeXHR;
434
542
  win.fetch = winAh.fakeFetch;
435
543
  resProto.clone = winAh.fakeFetchClone;
436
544
  winAh.hookInsts.add(hookInst);
437
545
  return {
438
- hook: fn => hookInst.hookFns.push(fn),
439
- filter: arr => {
546
+ hook: (fn) => hookInst.hookFns.push(fn),
547
+ filter: (arr) => {
440
548
  if (Array.isArray(arr)) hookInst.filters = arr;
441
549
  },
442
550
  protect: () => {
443
- readonly(win, 'XMLHttpRequest', winAh.fakeXHR);
444
- readonly(win, 'fetch', winAh.fakeFetch);
445
- readonly(resProto, 'clone', winAh.fakeFetchClone);
551
+ readonly(win, "XMLHttpRequest", winAh.fakeXHR);
552
+ readonly(win, "fetch", winAh.fakeFetch);
553
+ readonly(resProto, "clone", winAh.fakeFetchClone);
446
554
  },
447
555
  unhook: () => {
448
556
  winAh.hookInsts.delete(hookInst);
449
557
  if (!winAh.hookInsts.size) {
450
- writable(win, 'XMLHttpRequest', winAh.realXHR);
451
- writable(win, 'fetch', winAh.realFetch);
452
- writable(resProto, 'clone', winAh.realFetchClone);
558
+ writable(win, "XMLHttpRequest", winAh.realXHR);
559
+ writable(win, "fetch", winAh.realFetch);
560
+ writable(resProto, "clone", winAh.realFetchClone);
453
561
  delete win.__ajaxHooker;
454
562
  }
455
- }
563
+ },
456
564
  };
457
- }();
565
+ })();
458
566
  };
459
-
460
- export { AjaxHooker };