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