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