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