@whitesev/utils 1.5.5 → 1.5.7
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/dist/index.amd.js +259 -153
- package/dist/index.amd.js.map +1 -1
- package/dist/index.cjs.js +259 -153
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +259 -153
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +259 -153
- package/dist/index.iife.js.map +1 -1
- package/dist/index.system.js +259 -153
- package/dist/index.system.js.map +1 -1
- package/dist/index.umd.js +259 -153
- package/dist/index.umd.js.map +1 -1
- package/dist/src/AjaxHookerType.d.ts +147 -0
- package/dist/src/Utils.d.ts +1 -0
- package/package.json +1 -1
- package/src/{ajaxHooker/index.d.ts → AjaxHookerType.ts} +6 -4
- package/src/Utils.ts +1 -1
- package/src/ajaxHooker/ajaxHooker.js +261 -156
package/dist/index.esm.js
CHANGED
|
@@ -455,7 +455,6 @@ class UtilsGMCookie {
|
|
|
455
455
|
}
|
|
456
456
|
}
|
|
457
457
|
|
|
458
|
-
/// <reference path="./index.d.ts" />
|
|
459
458
|
// @name ajaxHooker
|
|
460
459
|
// @author cxxjackie
|
|
461
460
|
// @version 1.4.3
|
|
@@ -464,26 +463,43 @@ class UtilsGMCookie {
|
|
|
464
463
|
// @supportURL https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
|
|
465
464
|
|
|
466
465
|
const AjaxHooker = function () {
|
|
467
|
-
return function() {
|
|
468
|
-
const version =
|
|
466
|
+
return (function () {
|
|
467
|
+
const version = "1.4.3";
|
|
469
468
|
const hookInst = {
|
|
470
469
|
hookFns: [],
|
|
471
|
-
filters: []
|
|
470
|
+
filters: [],
|
|
472
471
|
};
|
|
473
472
|
const win = window.unsafeWindow || document.defaultView || window;
|
|
474
473
|
let winAh = win.__ajaxHooker;
|
|
475
474
|
const resProto = win.Response.prototype;
|
|
476
|
-
const xhrResponses = [
|
|
477
|
-
const fetchResponses = [
|
|
478
|
-
const fetchInitProps = [
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
475
|
+
const xhrResponses = ["response", "responseText", "responseXML"];
|
|
476
|
+
const fetchResponses = ["arrayBuffer", "blob", "formData", "json", "text"];
|
|
477
|
+
const fetchInitProps = [
|
|
478
|
+
"method",
|
|
479
|
+
"headers",
|
|
480
|
+
"body",
|
|
481
|
+
"mode",
|
|
482
|
+
"credentials",
|
|
483
|
+
"cache",
|
|
484
|
+
"redirect",
|
|
485
|
+
"referrer",
|
|
486
|
+
"referrerPolicy",
|
|
487
|
+
"integrity",
|
|
488
|
+
"keepalive",
|
|
489
|
+
"signal",
|
|
490
|
+
"priority",
|
|
491
|
+
];
|
|
492
|
+
const xhrAsyncEvents = ["readystatechange", "load", "loadend"];
|
|
493
|
+
const getType = {}.toString.call.bind({}.toString);
|
|
482
494
|
const getDescriptor = Object.getOwnPropertyDescriptor.bind(Object);
|
|
483
495
|
const emptyFn = () => {};
|
|
484
|
-
const errorFn = e => console.error(e);
|
|
496
|
+
const errorFn = (e) => console.error(e);
|
|
485
497
|
function isThenable(obj) {
|
|
486
|
-
return
|
|
498
|
+
return (
|
|
499
|
+
obj &&
|
|
500
|
+
["object", "function"].includes(typeof obj) &&
|
|
501
|
+
typeof obj.then === "function"
|
|
502
|
+
);
|
|
487
503
|
}
|
|
488
504
|
function catchError(fn, ...args) {
|
|
489
505
|
try {
|
|
@@ -499,7 +515,7 @@ const AjaxHooker = function () {
|
|
|
499
515
|
configurable: true,
|
|
500
516
|
enumerable: true,
|
|
501
517
|
get: getter,
|
|
502
|
-
set: setter
|
|
518
|
+
set: setter,
|
|
503
519
|
});
|
|
504
520
|
}
|
|
505
521
|
function readonly(obj, prop, value = obj[prop]) {
|
|
@@ -510,27 +526,28 @@ const AjaxHooker = function () {
|
|
|
510
526
|
configurable: true,
|
|
511
527
|
enumerable: true,
|
|
512
528
|
writable: true,
|
|
513
|
-
value: value
|
|
529
|
+
value: value,
|
|
514
530
|
});
|
|
515
531
|
}
|
|
516
532
|
function parseHeaders(obj) {
|
|
517
533
|
const headers = {};
|
|
518
534
|
switch (getType(obj)) {
|
|
519
|
-
case
|
|
535
|
+
case "[object String]":
|
|
520
536
|
for (const line of obj.trim().split(/[\r\n]+/)) {
|
|
521
537
|
const [header, value] = line.split(/\s*:\s*/);
|
|
522
538
|
if (!header) break;
|
|
523
539
|
const lheader = header.toLowerCase();
|
|
524
|
-
headers[lheader] =
|
|
540
|
+
headers[lheader] =
|
|
541
|
+
lheader in headers ? `${headers[lheader]}, ${value}` : value;
|
|
525
542
|
}
|
|
526
543
|
break;
|
|
527
|
-
case
|
|
544
|
+
case "[object Headers]":
|
|
528
545
|
for (const [key, val] of obj) {
|
|
529
546
|
headers[key] = val;
|
|
530
547
|
}
|
|
531
548
|
break;
|
|
532
|
-
case
|
|
533
|
-
return {...obj};
|
|
549
|
+
case "[object Object]":
|
|
550
|
+
return { ...obj };
|
|
534
551
|
}
|
|
535
552
|
return headers;
|
|
536
553
|
}
|
|
@@ -546,104 +563,142 @@ const AjaxHooker = function () {
|
|
|
546
563
|
class AHRequest {
|
|
547
564
|
constructor(request) {
|
|
548
565
|
this.request = request;
|
|
549
|
-
this.requestClone = {...this.request};
|
|
566
|
+
this.requestClone = { ...this.request };
|
|
550
567
|
}
|
|
551
568
|
shouldFilter(filters) {
|
|
552
|
-
const {type, url, method, async} = this.request;
|
|
553
|
-
return
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
569
|
+
const { type, url, method, async } = this.request;
|
|
570
|
+
return (
|
|
571
|
+
filters.length &&
|
|
572
|
+
!filters.find((obj) => {
|
|
573
|
+
switch (true) {
|
|
574
|
+
case obj.type && obj.type !== type:
|
|
575
|
+
case getType(obj.url) === "[object String]" &&
|
|
576
|
+
!url.includes(obj.url):
|
|
577
|
+
case getType(obj.url) === "[object RegExp]" && !obj.url.test(url):
|
|
578
|
+
case obj.method &&
|
|
579
|
+
obj.method.toUpperCase() !== method.toUpperCase():
|
|
580
|
+
case "async" in obj && obj.async !== async:
|
|
581
|
+
return false;
|
|
582
|
+
}
|
|
583
|
+
return true;
|
|
584
|
+
})
|
|
585
|
+
);
|
|
564
586
|
}
|
|
565
587
|
waitForRequestKeys() {
|
|
566
|
-
const requestKeys = [
|
|
588
|
+
const requestKeys = ["url", "method", "abort", "headers", "data"];
|
|
567
589
|
if (!this.request.async) {
|
|
568
|
-
win.__ajaxHooker.hookInsts.forEach(({hookFns, filters}) => {
|
|
590
|
+
win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
|
|
569
591
|
if (this.shouldFilter(filters)) return;
|
|
570
|
-
hookFns.forEach(fn => {
|
|
571
|
-
if (getType(fn) ===
|
|
592
|
+
hookFns.forEach((fn) => {
|
|
593
|
+
if (getType(fn) === "[object Function]")
|
|
594
|
+
catchError(fn, this.request);
|
|
572
595
|
});
|
|
573
|
-
requestKeys.forEach(key => {
|
|
574
|
-
if (isThenable(this.request[key]))
|
|
596
|
+
requestKeys.forEach((key) => {
|
|
597
|
+
if (isThenable(this.request[key]))
|
|
598
|
+
this.request[key] = this.requestClone[key];
|
|
575
599
|
});
|
|
576
600
|
});
|
|
577
601
|
return new SyncThenable();
|
|
578
602
|
}
|
|
579
603
|
const promises = [];
|
|
580
|
-
win.__ajaxHooker.hookInsts.forEach(({hookFns, filters}) => {
|
|
604
|
+
win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
|
|
581
605
|
if (this.shouldFilter(filters)) return;
|
|
582
|
-
promises.push(
|
|
583
|
-
Promise.all(
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
606
|
+
promises.push(
|
|
607
|
+
Promise.all(hookFns.map((fn) => catchError(fn, this.request))).then(
|
|
608
|
+
() =>
|
|
609
|
+
Promise.all(
|
|
610
|
+
requestKeys.map((key) =>
|
|
611
|
+
Promise.resolve(this.request[key]).then(
|
|
612
|
+
(val) => (this.request[key] = val),
|
|
613
|
+
() => (this.request[key] = this.requestClone[key])
|
|
614
|
+
)
|
|
615
|
+
)
|
|
616
|
+
)
|
|
617
|
+
)
|
|
618
|
+
);
|
|
588
619
|
});
|
|
589
620
|
return Promise.all(promises);
|
|
590
621
|
}
|
|
591
622
|
waitForResponseKeys(response) {
|
|
592
|
-
const responseKeys =
|
|
623
|
+
const responseKeys =
|
|
624
|
+
this.request.type === "xhr" ? xhrResponses : fetchResponses;
|
|
593
625
|
if (!this.request.async) {
|
|
594
|
-
if (getType(this.request.response) ===
|
|
626
|
+
if (getType(this.request.response) === "[object Function]") {
|
|
595
627
|
catchError(this.request.response, response);
|
|
596
|
-
responseKeys.forEach(key => {
|
|
597
|
-
if (
|
|
628
|
+
responseKeys.forEach((key) => {
|
|
629
|
+
if (
|
|
630
|
+
"get" in getDescriptor(response, key) ||
|
|
631
|
+
isThenable(response[key])
|
|
632
|
+
) {
|
|
598
633
|
delete response[key];
|
|
599
634
|
}
|
|
600
635
|
});
|
|
601
636
|
}
|
|
602
637
|
return new SyncThenable();
|
|
603
638
|
}
|
|
604
|
-
return Promise.resolve(
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
639
|
+
return Promise.resolve(
|
|
640
|
+
catchError(this.request.response, response)
|
|
641
|
+
).then(() =>
|
|
642
|
+
Promise.all(
|
|
643
|
+
responseKeys.map((key) => {
|
|
644
|
+
const descriptor = getDescriptor(response, key);
|
|
645
|
+
if (descriptor && "value" in descriptor) {
|
|
646
|
+
return Promise.resolve(descriptor.value).then(
|
|
647
|
+
(val) => (response[key] = val),
|
|
648
|
+
() => delete response[key]
|
|
649
|
+
);
|
|
650
|
+
} else {
|
|
651
|
+
delete response[key];
|
|
652
|
+
}
|
|
653
|
+
})
|
|
654
|
+
)
|
|
616
655
|
);
|
|
617
656
|
}
|
|
618
657
|
}
|
|
619
658
|
const proxyHandler = {
|
|
620
659
|
get(target, prop) {
|
|
621
660
|
const descriptor = getDescriptor(target, prop);
|
|
622
|
-
if (
|
|
661
|
+
if (
|
|
662
|
+
descriptor &&
|
|
663
|
+
!descriptor.configurable &&
|
|
664
|
+
!descriptor.writable &&
|
|
665
|
+
!descriptor.get
|
|
666
|
+
)
|
|
667
|
+
return target[prop];
|
|
623
668
|
const ah = target.__ajaxHooker;
|
|
624
669
|
if (ah && ah.proxyProps) {
|
|
625
670
|
if (prop in ah.proxyProps) {
|
|
626
671
|
const pDescriptor = ah.proxyProps[prop];
|
|
627
|
-
if (
|
|
628
|
-
if (typeof pDescriptor.value ===
|
|
672
|
+
if ("get" in pDescriptor) return pDescriptor.get();
|
|
673
|
+
if (typeof pDescriptor.value === "function")
|
|
674
|
+
return pDescriptor.value.bind(ah);
|
|
629
675
|
return pDescriptor.value;
|
|
630
676
|
}
|
|
631
|
-
if (typeof target[prop] ===
|
|
677
|
+
if (typeof target[prop] === "function")
|
|
678
|
+
return target[prop].bind(target);
|
|
632
679
|
}
|
|
633
680
|
return target[prop];
|
|
634
681
|
},
|
|
635
682
|
set(target, prop, value) {
|
|
636
683
|
const descriptor = getDescriptor(target, prop);
|
|
637
|
-
if (
|
|
684
|
+
if (
|
|
685
|
+
descriptor &&
|
|
686
|
+
!descriptor.configurable &&
|
|
687
|
+
!descriptor.writable &&
|
|
688
|
+
!descriptor.set
|
|
689
|
+
)
|
|
690
|
+
return true;
|
|
638
691
|
const ah = target.__ajaxHooker;
|
|
639
692
|
if (ah && ah.proxyProps && prop in ah.proxyProps) {
|
|
640
693
|
const pDescriptor = ah.proxyProps[prop];
|
|
641
|
-
pDescriptor.set
|
|
694
|
+
pDescriptor.set
|
|
695
|
+
? pDescriptor.set(value)
|
|
696
|
+
: (pDescriptor.value = value);
|
|
642
697
|
} else {
|
|
643
698
|
target[prop] = value;
|
|
644
699
|
}
|
|
645
700
|
return true;
|
|
646
|
-
}
|
|
701
|
+
},
|
|
647
702
|
};
|
|
648
703
|
class XhrHooker {
|
|
649
704
|
constructor(xhr) {
|
|
@@ -653,86 +708,113 @@ const AjaxHooker = function () {
|
|
|
653
708
|
proxyXhr: new Proxy(xhr, proxyHandler),
|
|
654
709
|
resThenable: new SyncThenable(),
|
|
655
710
|
proxyProps: {},
|
|
656
|
-
proxyEvents: {}
|
|
711
|
+
proxyEvents: {},
|
|
657
712
|
});
|
|
658
|
-
xhr.addEventListener(
|
|
659
|
-
if (
|
|
713
|
+
xhr.addEventListener("readystatechange", (e) => {
|
|
714
|
+
if (
|
|
715
|
+
ah.proxyXhr.readyState === 4 &&
|
|
716
|
+
ah.request &&
|
|
717
|
+
typeof ah.request.response === "function"
|
|
718
|
+
) {
|
|
660
719
|
const response = {
|
|
661
720
|
finalUrl: ah.proxyXhr.responseURL,
|
|
662
721
|
status: ah.proxyXhr.status,
|
|
663
|
-
responseHeaders: parseHeaders(
|
|
722
|
+
responseHeaders: parseHeaders(
|
|
723
|
+
ah.proxyXhr.getAllResponseHeaders()
|
|
724
|
+
),
|
|
664
725
|
};
|
|
665
726
|
const tempValues = {};
|
|
666
727
|
for (const key of xhrResponses) {
|
|
667
728
|
try {
|
|
668
729
|
tempValues[key] = ah.originalXhr[key];
|
|
669
730
|
} catch (err) {}
|
|
670
|
-
defineProp(
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
731
|
+
defineProp(
|
|
732
|
+
response,
|
|
733
|
+
key,
|
|
734
|
+
() => {
|
|
735
|
+
return (response[key] = tempValues[key]);
|
|
736
|
+
},
|
|
737
|
+
(val) => {
|
|
738
|
+
delete response[key];
|
|
739
|
+
response[key] = val;
|
|
740
|
+
}
|
|
741
|
+
);
|
|
676
742
|
}
|
|
677
|
-
ah.resThenable = new AHRequest(ah.request)
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
743
|
+
ah.resThenable = new AHRequest(ah.request)
|
|
744
|
+
.waitForResponseKeys(response)
|
|
745
|
+
.then(() => {
|
|
746
|
+
for (const key of xhrResponses) {
|
|
747
|
+
ah.proxyProps[key] = {
|
|
748
|
+
get: () => {
|
|
749
|
+
if (!(key in response)) response[key] = tempValues[key];
|
|
750
|
+
return response[key];
|
|
751
|
+
},
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
});
|
|
685
755
|
}
|
|
686
756
|
ah.dispatchEvent(e);
|
|
687
757
|
});
|
|
688
|
-
xhr.addEventListener(
|
|
689
|
-
xhr.addEventListener(
|
|
758
|
+
xhr.addEventListener("load", (e) => ah.dispatchEvent(e));
|
|
759
|
+
xhr.addEventListener("loadend", (e) => ah.dispatchEvent(e));
|
|
690
760
|
for (const evt of xhrAsyncEvents) {
|
|
691
|
-
const onEvt =
|
|
761
|
+
const onEvt = "on" + evt;
|
|
692
762
|
ah.proxyProps[onEvt] = {
|
|
693
763
|
get: () => ah.proxyEvents[onEvt] || null,
|
|
694
|
-
set: val => ah.addEvent(onEvt, val)
|
|
764
|
+
set: (val) => ah.addEvent(onEvt, val),
|
|
695
765
|
};
|
|
696
766
|
}
|
|
697
|
-
for (const method of [
|
|
698
|
-
|
|
767
|
+
for (const method of [
|
|
768
|
+
"setRequestHeader",
|
|
769
|
+
"addEventListener",
|
|
770
|
+
"removeEventListener",
|
|
771
|
+
"open",
|
|
772
|
+
"send",
|
|
773
|
+
]) {
|
|
774
|
+
ah.proxyProps[method] = { value: ah[method] };
|
|
699
775
|
}
|
|
700
776
|
}
|
|
701
777
|
toJSON() {} // Converting circular structure to JSON
|
|
702
778
|
addEvent(type, event) {
|
|
703
|
-
if (type.startsWith(
|
|
704
|
-
this.proxyEvents[type] = typeof event ===
|
|
779
|
+
if (type.startsWith("on")) {
|
|
780
|
+
this.proxyEvents[type] = typeof event === "function" ? event : null;
|
|
705
781
|
} else {
|
|
706
|
-
if (typeof event ===
|
|
707
|
-
|
|
782
|
+
if (typeof event === "object" && event !== null)
|
|
783
|
+
event = event.handleEvent;
|
|
784
|
+
if (typeof event !== "function") return;
|
|
708
785
|
this.proxyEvents[type] = this.proxyEvents[type] || new Set();
|
|
709
786
|
this.proxyEvents[type].add(event);
|
|
710
787
|
}
|
|
711
788
|
}
|
|
712
789
|
removeEvent(type, event) {
|
|
713
|
-
if (type.startsWith(
|
|
790
|
+
if (type.startsWith("on")) {
|
|
714
791
|
this.proxyEvents[type] = null;
|
|
715
792
|
} else {
|
|
716
|
-
if (typeof event ===
|
|
793
|
+
if (typeof event === "object" && event !== null)
|
|
794
|
+
event = event.handleEvent;
|
|
717
795
|
this.proxyEvents[type] && this.proxyEvents[type].delete(event);
|
|
718
796
|
}
|
|
719
797
|
}
|
|
720
798
|
dispatchEvent(e) {
|
|
721
799
|
e.stopImmediatePropagation = stopImmediatePropagation;
|
|
722
|
-
defineProp(e,
|
|
723
|
-
defineProp(e,
|
|
724
|
-
this.proxyEvents[e.type] &&
|
|
725
|
-
this.
|
|
726
|
-
|
|
800
|
+
defineProp(e, "target", () => this.proxyXhr);
|
|
801
|
+
defineProp(e, "currentTarget", () => this.proxyXhr);
|
|
802
|
+
this.proxyEvents[e.type] &&
|
|
803
|
+
this.proxyEvents[e.type].forEach((fn) => {
|
|
804
|
+
this.resThenable.then(
|
|
805
|
+
() => !e.ajaxHooker_isStopped && fn.call(this.proxyXhr, e)
|
|
806
|
+
);
|
|
807
|
+
});
|
|
727
808
|
if (e.ajaxHooker_isStopped) return;
|
|
728
|
-
const onEvent = this.proxyEvents[
|
|
809
|
+
const onEvent = this.proxyEvents["on" + e.type];
|
|
729
810
|
onEvent && this.resThenable.then(onEvent.bind(this.proxyXhr, e));
|
|
730
811
|
}
|
|
731
812
|
setRequestHeader(header, value) {
|
|
732
813
|
this.originalXhr.setRequestHeader(header, value);
|
|
733
814
|
if (!this.request) return;
|
|
734
815
|
const headers = this.request.headers;
|
|
735
|
-
headers[header] =
|
|
816
|
+
headers[header] =
|
|
817
|
+
header in headers ? `${headers[header]}, ${value}` : value;
|
|
736
818
|
}
|
|
737
819
|
addEventListener(...args) {
|
|
738
820
|
if (xhrAsyncEvents.includes(args[0])) {
|
|
@@ -750,18 +832,24 @@ const AjaxHooker = function () {
|
|
|
750
832
|
}
|
|
751
833
|
open(method, url, async = true, ...args) {
|
|
752
834
|
this.request = {
|
|
753
|
-
type:
|
|
835
|
+
type: "xhr",
|
|
754
836
|
url: url.toString(),
|
|
755
837
|
method: method.toUpperCase(),
|
|
756
838
|
abort: false,
|
|
757
839
|
headers: {},
|
|
758
840
|
data: null,
|
|
759
841
|
response: null,
|
|
760
|
-
async: !!async
|
|
842
|
+
async: !!async,
|
|
761
843
|
};
|
|
762
844
|
this.openArgs = args;
|
|
763
845
|
this.resThenable = new SyncThenable();
|
|
764
|
-
[
|
|
846
|
+
[
|
|
847
|
+
"responseURL",
|
|
848
|
+
"readyState",
|
|
849
|
+
"status",
|
|
850
|
+
"statusText",
|
|
851
|
+
...xhrResponses,
|
|
852
|
+
].forEach((key) => {
|
|
765
853
|
delete this.proxyProps[key];
|
|
766
854
|
});
|
|
767
855
|
return this.originalXhr.open(method, url, async, ...args);
|
|
@@ -774,17 +862,24 @@ const AjaxHooker = function () {
|
|
|
774
862
|
request.data = data;
|
|
775
863
|
new AHRequest(request).waitForRequestKeys().then(() => {
|
|
776
864
|
if (request.abort) {
|
|
777
|
-
if (typeof request.response ===
|
|
865
|
+
if (typeof request.response === "function") {
|
|
778
866
|
Object.assign(ah.proxyProps, {
|
|
779
|
-
responseURL: {value: request.url},
|
|
780
|
-
readyState: {value: 4},
|
|
781
|
-
status: {value: 200},
|
|
782
|
-
statusText: {value:
|
|
867
|
+
responseURL: { value: request.url },
|
|
868
|
+
readyState: { value: 4 },
|
|
869
|
+
status: { value: 200 },
|
|
870
|
+
statusText: { value: "OK" },
|
|
783
871
|
});
|
|
784
|
-
xhrAsyncEvents.forEach(evt =>
|
|
872
|
+
xhrAsyncEvents.forEach((evt) =>
|
|
873
|
+
xhr.dispatchEvent(new Event(evt))
|
|
874
|
+
);
|
|
785
875
|
}
|
|
786
876
|
} else {
|
|
787
|
-
xhr.open(
|
|
877
|
+
xhr.open(
|
|
878
|
+
request.method,
|
|
879
|
+
request.url,
|
|
880
|
+
request.async,
|
|
881
|
+
...ah.openArgs
|
|
882
|
+
);
|
|
788
883
|
for (const header in request.headers) {
|
|
789
884
|
xhr.setRequestHeader(header, request.headers[header]);
|
|
790
885
|
}
|
|
@@ -795,79 +890,87 @@ const AjaxHooker = function () {
|
|
|
795
890
|
}
|
|
796
891
|
function fakeXHR() {
|
|
797
892
|
const xhr = new winAh.realXHR();
|
|
798
|
-
if (
|
|
893
|
+
if ("__ajaxHooker" in xhr)
|
|
894
|
+
console.warn("检测到不同版本的ajaxHooker,可能发生冲突!");
|
|
799
895
|
xhr.__ajaxHooker = new XhrHooker(xhr);
|
|
800
896
|
return xhr.__ajaxHooker.proxyXhr;
|
|
801
897
|
}
|
|
802
898
|
fakeXHR.prototype = win.XMLHttpRequest.prototype;
|
|
803
|
-
Object.keys(win.XMLHttpRequest).forEach(
|
|
899
|
+
Object.keys(win.XMLHttpRequest).forEach(
|
|
900
|
+
(key) => (fakeXHR[key] = win.XMLHttpRequest[key])
|
|
901
|
+
);
|
|
804
902
|
function fakeFetch(url, options = {}) {
|
|
805
903
|
if (!url) return winAh.realFetch.call(win, url, options);
|
|
806
904
|
return new Promise(async (resolve, reject) => {
|
|
807
905
|
const init = {};
|
|
808
|
-
if (getType(url) ===
|
|
906
|
+
if (getType(url) === "[object Request]") {
|
|
809
907
|
for (const prop of fetchInitProps) init[prop] = url[prop];
|
|
810
908
|
if (url.body) init.body = await url.arrayBuffer();
|
|
811
909
|
url = url.url;
|
|
812
910
|
}
|
|
813
911
|
url = url.toString();
|
|
814
912
|
Object.assign(init, options);
|
|
815
|
-
init.method = init.method ||
|
|
913
|
+
init.method = init.method || "GET";
|
|
816
914
|
init.headers = init.headers || {};
|
|
817
915
|
const request = {
|
|
818
|
-
type:
|
|
916
|
+
type: "fetch",
|
|
819
917
|
url: url,
|
|
820
918
|
method: init.method.toUpperCase(),
|
|
821
919
|
abort: false,
|
|
822
920
|
headers: parseHeaders(init.headers),
|
|
823
921
|
data: init.body,
|
|
824
922
|
response: null,
|
|
825
|
-
async: true
|
|
923
|
+
async: true,
|
|
826
924
|
};
|
|
827
925
|
const req = new AHRequest(request);
|
|
828
926
|
await req.waitForRequestKeys();
|
|
829
927
|
if (request.abort) {
|
|
830
|
-
if (typeof request.response ===
|
|
928
|
+
if (typeof request.response === "function") {
|
|
831
929
|
const response = {
|
|
832
930
|
finalUrl: request.url,
|
|
833
931
|
status: 200,
|
|
834
|
-
responseHeaders: {}
|
|
932
|
+
responseHeaders: {},
|
|
835
933
|
};
|
|
836
934
|
await req.waitForResponseKeys(response);
|
|
837
|
-
const key = fetchResponses.find(k => k in response);
|
|
935
|
+
const key = fetchResponses.find((k) => k in response);
|
|
838
936
|
let val = response[key];
|
|
839
|
-
if (key ===
|
|
937
|
+
if (key === "json" && typeof val === "object") {
|
|
840
938
|
val = catchError(JSON.stringify.bind(JSON), val);
|
|
841
939
|
}
|
|
842
940
|
const res = new Response(val, {
|
|
843
941
|
status: 200,
|
|
844
|
-
statusText:
|
|
942
|
+
statusText: "OK",
|
|
845
943
|
});
|
|
846
|
-
defineProp(res,
|
|
847
|
-
defineProp(res,
|
|
944
|
+
defineProp(res, "type", () => "basic");
|
|
945
|
+
defineProp(res, "url", () => request.url);
|
|
848
946
|
resolve(res);
|
|
849
947
|
} else {
|
|
850
|
-
reject(new DOMException(
|
|
948
|
+
reject(new DOMException("aborted", "AbortError"));
|
|
851
949
|
}
|
|
852
950
|
return;
|
|
853
951
|
}
|
|
854
952
|
init.method = request.method;
|
|
855
953
|
init.headers = request.headers;
|
|
856
954
|
init.body = request.data;
|
|
857
|
-
winAh.realFetch.call(win, request.url, init).then(res => {
|
|
858
|
-
if (typeof request.response ===
|
|
955
|
+
winAh.realFetch.call(win, request.url, init).then((res) => {
|
|
956
|
+
if (typeof request.response === "function") {
|
|
859
957
|
const response = {
|
|
860
958
|
finalUrl: res.url,
|
|
861
959
|
status: res.status,
|
|
862
|
-
responseHeaders: parseHeaders(res.headers)
|
|
960
|
+
responseHeaders: parseHeaders(res.headers),
|
|
863
961
|
};
|
|
864
|
-
fetchResponses.forEach(
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
962
|
+
fetchResponses.forEach(
|
|
963
|
+
(key) =>
|
|
964
|
+
(res[key] = function () {
|
|
965
|
+
if (key in response) return Promise.resolve(response[key]);
|
|
966
|
+
return resProto[key].call(this).then((val) => {
|
|
967
|
+
response[key] = val;
|
|
968
|
+
return req
|
|
969
|
+
.waitForResponseKeys(response)
|
|
970
|
+
.then(() => (key in response ? response[key] : val));
|
|
971
|
+
});
|
|
972
|
+
})
|
|
973
|
+
);
|
|
871
974
|
}
|
|
872
975
|
resolve(res);
|
|
873
976
|
}, reject);
|
|
@@ -880,38 +983,42 @@ const AjaxHooker = function () {
|
|
|
880
983
|
return res;
|
|
881
984
|
}
|
|
882
985
|
winAh = win.__ajaxHooker = winAh || {
|
|
883
|
-
version,
|
|
986
|
+
version,
|
|
987
|
+
fakeXHR,
|
|
988
|
+
fakeFetch,
|
|
989
|
+
fakeFetchClone,
|
|
884
990
|
realXHR: win.XMLHttpRequest,
|
|
885
991
|
realFetch: win.fetch,
|
|
886
992
|
realFetchClone: resProto.clone,
|
|
887
|
-
hookInsts: new Set()
|
|
993
|
+
hookInsts: new Set(),
|
|
888
994
|
};
|
|
889
|
-
if (winAh.version !== version)
|
|
995
|
+
if (winAh.version !== version)
|
|
996
|
+
console.warn("检测到不同版本的ajaxHooker,可能发生冲突!");
|
|
890
997
|
win.XMLHttpRequest = winAh.fakeXHR;
|
|
891
998
|
win.fetch = winAh.fakeFetch;
|
|
892
999
|
resProto.clone = winAh.fakeFetchClone;
|
|
893
1000
|
winAh.hookInsts.add(hookInst);
|
|
894
1001
|
return {
|
|
895
|
-
hook: fn => hookInst.hookFns.push(fn),
|
|
896
|
-
filter: arr => {
|
|
1002
|
+
hook: (fn) => hookInst.hookFns.push(fn),
|
|
1003
|
+
filter: (arr) => {
|
|
897
1004
|
if (Array.isArray(arr)) hookInst.filters = arr;
|
|
898
1005
|
},
|
|
899
1006
|
protect: () => {
|
|
900
|
-
readonly(win,
|
|
901
|
-
readonly(win,
|
|
902
|
-
readonly(resProto,
|
|
1007
|
+
readonly(win, "XMLHttpRequest", winAh.fakeXHR);
|
|
1008
|
+
readonly(win, "fetch", winAh.fakeFetch);
|
|
1009
|
+
readonly(resProto, "clone", winAh.fakeFetchClone);
|
|
903
1010
|
},
|
|
904
1011
|
unhook: () => {
|
|
905
1012
|
winAh.hookInsts.delete(hookInst);
|
|
906
1013
|
if (!winAh.hookInsts.size) {
|
|
907
|
-
writable(win,
|
|
908
|
-
writable(win,
|
|
909
|
-
writable(resProto,
|
|
1014
|
+
writable(win, "XMLHttpRequest", winAh.realXHR);
|
|
1015
|
+
writable(win, "fetch", winAh.realFetch);
|
|
1016
|
+
writable(resProto, "clone", winAh.realFetchClone);
|
|
910
1017
|
delete win.__ajaxHooker;
|
|
911
1018
|
}
|
|
912
|
-
}
|
|
1019
|
+
},
|
|
913
1020
|
};
|
|
914
|
-
}();
|
|
1021
|
+
})();
|
|
915
1022
|
};
|
|
916
1023
|
|
|
917
1024
|
class GMMenu {
|
|
@@ -3281,7 +3388,6 @@ class UtilsDictionary {
|
|
|
3281
3388
|
}
|
|
3282
3389
|
}
|
|
3283
3390
|
|
|
3284
|
-
/// <reference path="./ajaxHooker/index.d.ts" />
|
|
3285
3391
|
class Utils {
|
|
3286
3392
|
constructor(option) {
|
|
3287
3393
|
UtilsCore.init(option);
|