@whitesev/utils 2.6.9 → 2.7.0
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 +584 -602
- package/dist/index.amd.js.map +1 -1
- package/dist/index.cjs.js +584 -602
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +584 -602
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +584 -602
- package/dist/index.iife.js.map +1 -1
- package/dist/index.system.js +584 -602
- package/dist/index.system.js.map +1 -1
- package/dist/index.umd.js +584 -602
- package/dist/index.umd.js.map +1 -1
- package/dist/types/src/Utils.d.ts +1 -1
- package/dist/types/src/ajaxHooker/ajaxHooker.d.ts +1 -1
- package/package.json +11 -9
- package/src/Utils.ts +4 -4
- package/src/ajaxHooker/ajaxHooker.js +536 -554
package/dist/index.umd.js
CHANGED
|
@@ -269,7 +269,7 @@
|
|
|
269
269
|
context = __context__ || this;
|
|
270
270
|
let result = executeTryCatch(callbackFunction, handleError, context);
|
|
271
271
|
// @ts-ignore
|
|
272
|
-
return result !==
|
|
272
|
+
return result !== void 0 ? result : TryCatchCore;
|
|
273
273
|
},
|
|
274
274
|
};
|
|
275
275
|
/**
|
|
@@ -280,7 +280,7 @@
|
|
|
280
280
|
* @returns 如果函数有返回值,则返回该返回值;否则返回 undefined。
|
|
281
281
|
*/
|
|
282
282
|
function executeTryCatch(callback, handleErrorFunc, funcThis) {
|
|
283
|
-
let result =
|
|
283
|
+
let result = void 0;
|
|
284
284
|
try {
|
|
285
285
|
if (typeof callback === "string") {
|
|
286
286
|
result = new Function(callback).apply(funcThis, args);
|
|
@@ -427,8 +427,8 @@
|
|
|
427
427
|
}
|
|
428
428
|
deepClone(obj) {
|
|
429
429
|
let UtilsContext = this;
|
|
430
|
-
if (obj ===
|
|
431
|
-
return
|
|
430
|
+
if (obj === void 0)
|
|
431
|
+
return void 0;
|
|
432
432
|
if (obj === null)
|
|
433
433
|
return null;
|
|
434
434
|
let clone = obj instanceof Array ? [] : {};
|
|
@@ -525,7 +525,7 @@
|
|
|
525
525
|
throw new TypeError("Utils.GMCookie.get 参数cookieName 必须为字符串");
|
|
526
526
|
}
|
|
527
527
|
let cookies = this.getCookiesList();
|
|
528
|
-
let findValue =
|
|
528
|
+
let findValue = void 0;
|
|
529
529
|
for (const cookieItem of cookies) {
|
|
530
530
|
let item = cookieItem.trim();
|
|
531
531
|
let itemSplit = item.split("=");
|
|
@@ -749,189 +749,189 @@
|
|
|
749
749
|
}
|
|
750
750
|
}
|
|
751
751
|
|
|
752
|
+
// ==UserScript==
|
|
752
753
|
// @name ajaxHooker
|
|
753
754
|
// @author cxxjackie
|
|
754
|
-
// @version 1.4.
|
|
755
|
-
// @updateLog 修复头条、抖音部分站点下this引用错误的问题。
|
|
755
|
+
// @version 1.4.6
|
|
756
756
|
// @supportURL https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
|
|
757
|
+
// @license GNU LGPL-3.0
|
|
758
|
+
// ==/UserScript==
|
|
757
759
|
|
|
758
|
-
const
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
console.error(err);
|
|
804
|
-
}
|
|
760
|
+
const ajaxHooker = function () {
|
|
761
|
+
const version = "1.4.6";
|
|
762
|
+
const hookInst = {
|
|
763
|
+
hookFns: [],
|
|
764
|
+
filters: [],
|
|
765
|
+
};
|
|
766
|
+
const win = window.unsafeWindow || document.defaultView || window;
|
|
767
|
+
let winAh = win.__ajaxHooker;
|
|
768
|
+
const resProto = win.Response.prototype;
|
|
769
|
+
const xhrResponses = ["response", "responseText", "responseXML"];
|
|
770
|
+
const fetchResponses = ["arrayBuffer", "blob", "formData", "json", "text"];
|
|
771
|
+
const fetchInitProps = [
|
|
772
|
+
"method",
|
|
773
|
+
"headers",
|
|
774
|
+
"body",
|
|
775
|
+
"mode",
|
|
776
|
+
"credentials",
|
|
777
|
+
"cache",
|
|
778
|
+
"redirect",
|
|
779
|
+
"referrer",
|
|
780
|
+
"referrerPolicy",
|
|
781
|
+
"integrity",
|
|
782
|
+
"keepalive",
|
|
783
|
+
"signal",
|
|
784
|
+
"priority",
|
|
785
|
+
];
|
|
786
|
+
const xhrAsyncEvents = ["readystatechange", "load", "loadend"];
|
|
787
|
+
const getType = {}.toString.call.bind({}.toString);
|
|
788
|
+
const getDescriptor = Object.getOwnPropertyDescriptor.bind(Object);
|
|
789
|
+
const emptyFn = () => {};
|
|
790
|
+
const errorFn = (e) => console.error(e);
|
|
791
|
+
function isThenable(obj) {
|
|
792
|
+
return (
|
|
793
|
+
obj &&
|
|
794
|
+
["object", "function"].includes(typeof obj) &&
|
|
795
|
+
typeof obj.then === "function"
|
|
796
|
+
);
|
|
797
|
+
}
|
|
798
|
+
function catchError(fn, ...args) {
|
|
799
|
+
try {
|
|
800
|
+
const result = fn(...args);
|
|
801
|
+
if (isThenable(result)) return result.then(null, errorFn);
|
|
802
|
+
return result;
|
|
803
|
+
} catch (err) {
|
|
804
|
+
console.error(err);
|
|
805
805
|
}
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
806
|
+
}
|
|
807
|
+
function defineProp(obj, prop, getter, setter) {
|
|
808
|
+
Object.defineProperty(obj, prop, {
|
|
809
|
+
configurable: true,
|
|
810
|
+
enumerable: true,
|
|
811
|
+
get: getter,
|
|
812
|
+
set: setter,
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
function readonly(obj, prop, value = obj[prop]) {
|
|
816
|
+
defineProp(obj, prop, () => value, emptyFn);
|
|
817
|
+
}
|
|
818
|
+
function writable(obj, prop, value = obj[prop]) {
|
|
819
|
+
Object.defineProperty(obj, prop, {
|
|
820
|
+
configurable: true,
|
|
821
|
+
enumerable: true,
|
|
822
|
+
writable: true,
|
|
823
|
+
value: value,
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
function parseHeaders(obj) {
|
|
827
|
+
const headers = {};
|
|
828
|
+
switch (getType(obj)) {
|
|
829
|
+
case "[object String]":
|
|
830
|
+
for (const line of obj.trim().split(/[\r\n]+/)) {
|
|
831
|
+
const [header, value] = line.split(/(?<=^[^:]+)\s*:\s*/);
|
|
832
|
+
if (!value) continue;
|
|
833
|
+
const lheader = header.toLowerCase();
|
|
834
|
+
headers[lheader] =
|
|
835
|
+
lheader in headers ? `${headers[lheader]}, ${value}` : value;
|
|
836
|
+
}
|
|
837
|
+
break;
|
|
838
|
+
case "[object Headers]":
|
|
839
|
+
for (const [key, val] of obj) {
|
|
840
|
+
headers[key] = val;
|
|
841
|
+
}
|
|
842
|
+
break;
|
|
843
|
+
case "[object Object]":
|
|
844
|
+
return { ...obj };
|
|
813
845
|
}
|
|
814
|
-
|
|
815
|
-
|
|
846
|
+
return headers;
|
|
847
|
+
}
|
|
848
|
+
function stopImmediatePropagation() {
|
|
849
|
+
this.ajaxHooker_isStopped = true;
|
|
850
|
+
}
|
|
851
|
+
class SyncThenable {
|
|
852
|
+
then(fn) {
|
|
853
|
+
fn && fn();
|
|
854
|
+
return new SyncThenable();
|
|
816
855
|
}
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
value: value,
|
|
823
|
-
});
|
|
856
|
+
}
|
|
857
|
+
class AHRequest {
|
|
858
|
+
constructor(request) {
|
|
859
|
+
this.request = request;
|
|
860
|
+
this.requestClone = { ...this.request };
|
|
824
861
|
}
|
|
825
|
-
|
|
826
|
-
const
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
headers[key] = val;
|
|
862
|
+
shouldFilter(filters) {
|
|
863
|
+
const { type, url, method, async } = this.request;
|
|
864
|
+
return (
|
|
865
|
+
filters.length &&
|
|
866
|
+
!filters.find((obj) => {
|
|
867
|
+
switch (true) {
|
|
868
|
+
case obj.type && obj.type !== type:
|
|
869
|
+
case getType(obj.url) === "[object String]" &&
|
|
870
|
+
!url.includes(obj.url):
|
|
871
|
+
case getType(obj.url) === "[object RegExp]" && !obj.url.test(url):
|
|
872
|
+
case obj.method &&
|
|
873
|
+
obj.method.toUpperCase() !== method.toUpperCase():
|
|
874
|
+
case "async" in obj && obj.async !== async:
|
|
875
|
+
return false;
|
|
840
876
|
}
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
}
|
|
845
|
-
return headers;
|
|
846
|
-
}
|
|
847
|
-
function stopImmediatePropagation() {
|
|
848
|
-
this.ajaxHooker_isStopped = true;
|
|
877
|
+
return true;
|
|
878
|
+
})
|
|
879
|
+
);
|
|
849
880
|
}
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
881
|
+
waitForRequestKeys() {
|
|
882
|
+
const requestKeys = ["url", "method", "abort", "headers", "data"];
|
|
883
|
+
if (!this.request.async) {
|
|
884
|
+
win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
|
|
885
|
+
if (this.shouldFilter(filters)) return;
|
|
886
|
+
hookFns.forEach((fn) => {
|
|
887
|
+
if (getType(fn) === "[object Function]")
|
|
888
|
+
catchError(fn, this.request);
|
|
889
|
+
});
|
|
890
|
+
requestKeys.forEach((key) => {
|
|
891
|
+
if (isThenable(this.request[key]))
|
|
892
|
+
this.request[key] = this.requestClone[key];
|
|
893
|
+
});
|
|
894
|
+
});
|
|
853
895
|
return new SyncThenable();
|
|
854
896
|
}
|
|
897
|
+
const promises = [];
|
|
898
|
+
win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
|
|
899
|
+
if (this.shouldFilter(filters)) return;
|
|
900
|
+
promises.push(
|
|
901
|
+
Promise.all(hookFns.map((fn) => catchError(fn, this.request))).then(
|
|
902
|
+
() =>
|
|
903
|
+
Promise.all(
|
|
904
|
+
requestKeys.map((key) =>
|
|
905
|
+
Promise.resolve(this.request[key]).then(
|
|
906
|
+
(val) => (this.request[key] = val),
|
|
907
|
+
() => (this.request[key] = this.requestClone[key])
|
|
908
|
+
)
|
|
909
|
+
)
|
|
910
|
+
)
|
|
911
|
+
)
|
|
912
|
+
);
|
|
913
|
+
});
|
|
914
|
+
return Promise.all(promises);
|
|
855
915
|
}
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
this.request
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
case getType(obj.url) === "[object String]" &&
|
|
869
|
-
!url.includes(obj.url):
|
|
870
|
-
case getType(obj.url) === "[object RegExp]" && !obj.url.test(url):
|
|
871
|
-
case obj.method &&
|
|
872
|
-
obj.method.toUpperCase() !== method.toUpperCase():
|
|
873
|
-
case "async" in obj && obj.async !== async:
|
|
874
|
-
return false;
|
|
916
|
+
waitForResponseKeys(response) {
|
|
917
|
+
const responseKeys =
|
|
918
|
+
this.request.type === "xhr" ? xhrResponses : fetchResponses;
|
|
919
|
+
if (!this.request.async) {
|
|
920
|
+
if (getType(this.request.response) === "[object Function]") {
|
|
921
|
+
catchError(this.request.response, response);
|
|
922
|
+
responseKeys.forEach((key) => {
|
|
923
|
+
if (
|
|
924
|
+
"get" in getDescriptor(response, key) ||
|
|
925
|
+
isThenable(response[key])
|
|
926
|
+
) {
|
|
927
|
+
delete response[key];
|
|
875
928
|
}
|
|
876
|
-
return true;
|
|
877
|
-
})
|
|
878
|
-
);
|
|
879
|
-
}
|
|
880
|
-
waitForRequestKeys() {
|
|
881
|
-
const requestKeys = ["url", "method", "abort", "headers", "data"];
|
|
882
|
-
if (!this.request.async) {
|
|
883
|
-
win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
|
|
884
|
-
if (this.shouldFilter(filters)) return;
|
|
885
|
-
hookFns.forEach((fn) => {
|
|
886
|
-
if (getType(fn) === "[object Function]")
|
|
887
|
-
catchError(fn, this.request);
|
|
888
|
-
});
|
|
889
|
-
requestKeys.forEach((key) => {
|
|
890
|
-
if (isThenable(this.request[key]))
|
|
891
|
-
this.request[key] = this.requestClone[key];
|
|
892
|
-
});
|
|
893
929
|
});
|
|
894
|
-
return new SyncThenable();
|
|
895
930
|
}
|
|
896
|
-
|
|
897
|
-
win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
|
|
898
|
-
if (this.shouldFilter(filters)) return;
|
|
899
|
-
promises.push(
|
|
900
|
-
Promise.all(hookFns.map((fn) => catchError(fn, this.request))).then(
|
|
901
|
-
() =>
|
|
902
|
-
Promise.all(
|
|
903
|
-
requestKeys.map((key) =>
|
|
904
|
-
Promise.resolve(this.request[key]).then(
|
|
905
|
-
(val) => (this.request[key] = val),
|
|
906
|
-
() => (this.request[key] = this.requestClone[key])
|
|
907
|
-
)
|
|
908
|
-
)
|
|
909
|
-
)
|
|
910
|
-
)
|
|
911
|
-
);
|
|
912
|
-
});
|
|
913
|
-
return Promise.all(promises);
|
|
931
|
+
return new SyncThenable();
|
|
914
932
|
}
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
this.request.type === "xhr" ? xhrResponses : fetchResponses;
|
|
918
|
-
if (!this.request.async) {
|
|
919
|
-
if (getType(this.request.response) === "[object Function]") {
|
|
920
|
-
catchError(this.request.response, response);
|
|
921
|
-
responseKeys.forEach((key) => {
|
|
922
|
-
if (
|
|
923
|
-
"get" in getDescriptor(response, key) ||
|
|
924
|
-
isThenable(response[key])
|
|
925
|
-
) {
|
|
926
|
-
delete response[key];
|
|
927
|
-
}
|
|
928
|
-
});
|
|
929
|
-
}
|
|
930
|
-
return new SyncThenable();
|
|
931
|
-
}
|
|
932
|
-
return Promise.resolve(
|
|
933
|
-
catchError(this.request.response, response)
|
|
934
|
-
).then(() =>
|
|
933
|
+
return Promise.resolve(catchError(this.request.response, response)).then(
|
|
934
|
+
() =>
|
|
935
935
|
Promise.all(
|
|
936
936
|
responseKeys.map((key) => {
|
|
937
937
|
const descriptor = getDescriptor(response, key);
|
|
@@ -945,424 +945,406 @@
|
|
|
945
945
|
}
|
|
946
946
|
})
|
|
947
947
|
)
|
|
948
|
-
|
|
949
|
-
}
|
|
948
|
+
);
|
|
950
949
|
}
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
const ah = target.__ajaxHooker;
|
|
962
|
-
if (ah && ah.proxyProps) {
|
|
963
|
-
if (prop in ah.proxyProps) {
|
|
964
|
-
const pDescriptor = ah.proxyProps[prop];
|
|
965
|
-
if ("get" in pDescriptor) return pDescriptor.get();
|
|
966
|
-
if (typeof pDescriptor.value === "function")
|
|
967
|
-
return pDescriptor.value.bind(ah);
|
|
968
|
-
return pDescriptor.value;
|
|
969
|
-
}
|
|
970
|
-
if (typeof target[prop] === "function")
|
|
971
|
-
return target[prop].bind(target);
|
|
972
|
-
}
|
|
950
|
+
}
|
|
951
|
+
const proxyHandler = {
|
|
952
|
+
get(target, prop) {
|
|
953
|
+
const descriptor = getDescriptor(target, prop);
|
|
954
|
+
if (
|
|
955
|
+
descriptor &&
|
|
956
|
+
!descriptor.configurable &&
|
|
957
|
+
!descriptor.writable &&
|
|
958
|
+
!descriptor.get
|
|
959
|
+
)
|
|
973
960
|
return target[prop];
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
if (
|
|
978
|
-
descriptor &&
|
|
979
|
-
!descriptor.configurable &&
|
|
980
|
-
!descriptor.writable &&
|
|
981
|
-
!descriptor.set
|
|
982
|
-
)
|
|
983
|
-
return true;
|
|
984
|
-
const ah = target.__ajaxHooker;
|
|
985
|
-
if (ah && ah.proxyProps && prop in ah.proxyProps) {
|
|
961
|
+
const ah = target.__ajaxHooker;
|
|
962
|
+
if (ah && ah.proxyProps) {
|
|
963
|
+
if (prop in ah.proxyProps) {
|
|
986
964
|
const pDescriptor = ah.proxyProps[prop];
|
|
987
|
-
pDescriptor.
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
target[prop] = value;
|
|
992
|
-
}
|
|
993
|
-
return true;
|
|
994
|
-
},
|
|
995
|
-
};
|
|
996
|
-
class XhrHooker {
|
|
997
|
-
constructor(xhr) {
|
|
998
|
-
const ah = this;
|
|
999
|
-
Object.assign(ah, {
|
|
1000
|
-
originalXhr: xhr,
|
|
1001
|
-
proxyXhr: new Proxy(xhr, proxyHandler),
|
|
1002
|
-
resThenable: new SyncThenable(),
|
|
1003
|
-
proxyProps: {},
|
|
1004
|
-
proxyEvents: {},
|
|
1005
|
-
});
|
|
1006
|
-
xhr.addEventListener("readystatechange", (e) => {
|
|
1007
|
-
if (
|
|
1008
|
-
ah.proxyXhr.readyState === 4 &&
|
|
1009
|
-
ah.request &&
|
|
1010
|
-
typeof ah.request.response === "function"
|
|
1011
|
-
) {
|
|
1012
|
-
const response = {
|
|
1013
|
-
finalUrl: ah.proxyXhr.responseURL,
|
|
1014
|
-
status: ah.proxyXhr.status,
|
|
1015
|
-
responseHeaders: parseHeaders(
|
|
1016
|
-
ah.proxyXhr.getAllResponseHeaders()
|
|
1017
|
-
),
|
|
1018
|
-
};
|
|
1019
|
-
const tempValues = {};
|
|
1020
|
-
for (const key of xhrResponses) {
|
|
1021
|
-
try {
|
|
1022
|
-
tempValues[key] = ah.originalXhr[key];
|
|
1023
|
-
} catch (err) {}
|
|
1024
|
-
defineProp(
|
|
1025
|
-
response,
|
|
1026
|
-
key,
|
|
1027
|
-
() => {
|
|
1028
|
-
return (response[key] = tempValues[key]);
|
|
1029
|
-
},
|
|
1030
|
-
(val) => {
|
|
1031
|
-
delete response[key];
|
|
1032
|
-
response[key] = val;
|
|
1033
|
-
}
|
|
1034
|
-
);
|
|
1035
|
-
}
|
|
1036
|
-
ah.resThenable = new AHRequest(ah.request)
|
|
1037
|
-
.waitForResponseKeys(response)
|
|
1038
|
-
.then(() => {
|
|
1039
|
-
for (const key of xhrResponses) {
|
|
1040
|
-
ah.proxyProps[key] = {
|
|
1041
|
-
get: () => {
|
|
1042
|
-
if (!(key in response)) response[key] = tempValues[key];
|
|
1043
|
-
return response[key];
|
|
1044
|
-
},
|
|
1045
|
-
};
|
|
1046
|
-
}
|
|
1047
|
-
});
|
|
1048
|
-
}
|
|
1049
|
-
ah.dispatchEvent(e);
|
|
1050
|
-
});
|
|
1051
|
-
xhr.addEventListener("load", (e) => ah.dispatchEvent(e));
|
|
1052
|
-
xhr.addEventListener("loadend", (e) => ah.dispatchEvent(e));
|
|
1053
|
-
for (const evt of xhrAsyncEvents) {
|
|
1054
|
-
const onEvt = "on" + evt;
|
|
1055
|
-
ah.proxyProps[onEvt] = {
|
|
1056
|
-
get: () => ah.proxyEvents[onEvt] || null,
|
|
1057
|
-
set: (val) => ah.addEvent(onEvt, val),
|
|
1058
|
-
};
|
|
1059
|
-
}
|
|
1060
|
-
for (const method of [
|
|
1061
|
-
"setRequestHeader",
|
|
1062
|
-
"addEventListener",
|
|
1063
|
-
"removeEventListener",
|
|
1064
|
-
"open",
|
|
1065
|
-
"send",
|
|
1066
|
-
]) {
|
|
1067
|
-
ah.proxyProps[method] = { value: ah[method] };
|
|
965
|
+
if ("get" in pDescriptor) return pDescriptor.get();
|
|
966
|
+
if (typeof pDescriptor.value === "function")
|
|
967
|
+
return pDescriptor.value.bind(ah);
|
|
968
|
+
return pDescriptor.value;
|
|
1068
969
|
}
|
|
970
|
+
if (typeof target[prop] === "function")
|
|
971
|
+
return target[prop].bind(target);
|
|
1069
972
|
}
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
event = event.handleEvent;
|
|
1088
|
-
this.proxyEvents[type] && this.proxyEvents[type].delete(event);
|
|
1089
|
-
}
|
|
973
|
+
return target[prop];
|
|
974
|
+
},
|
|
975
|
+
set(target, prop, value) {
|
|
976
|
+
const descriptor = getDescriptor(target, prop);
|
|
977
|
+
if (
|
|
978
|
+
descriptor &&
|
|
979
|
+
!descriptor.configurable &&
|
|
980
|
+
!descriptor.writable &&
|
|
981
|
+
!descriptor.set
|
|
982
|
+
)
|
|
983
|
+
return true;
|
|
984
|
+
const ah = target.__ajaxHooker;
|
|
985
|
+
if (ah && ah.proxyProps && prop in ah.proxyProps) {
|
|
986
|
+
const pDescriptor = ah.proxyProps[prop];
|
|
987
|
+
pDescriptor.set ? pDescriptor.set(value) : (pDescriptor.value = value);
|
|
988
|
+
} else {
|
|
989
|
+
target[prop] = value;
|
|
1090
990
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
991
|
+
return true;
|
|
992
|
+
},
|
|
993
|
+
};
|
|
994
|
+
class XhrHooker {
|
|
995
|
+
constructor(xhr) {
|
|
996
|
+
const ah = this;
|
|
997
|
+
Object.assign(ah, {
|
|
998
|
+
originalXhr: xhr,
|
|
999
|
+
proxyXhr: new Proxy(xhr, proxyHandler),
|
|
1000
|
+
resThenable: new SyncThenable(),
|
|
1001
|
+
proxyProps: {},
|
|
1002
|
+
proxyEvents: {},
|
|
1003
|
+
});
|
|
1004
|
+
xhr.addEventListener("readystatechange", (e) => {
|
|
1005
|
+
if (
|
|
1006
|
+
ah.proxyXhr.readyState === 4 &&
|
|
1007
|
+
ah.request &&
|
|
1008
|
+
typeof ah.request.response === "function"
|
|
1009
|
+
) {
|
|
1010
|
+
const response = {
|
|
1011
|
+
finalUrl: ah.proxyXhr.responseURL,
|
|
1012
|
+
status: ah.proxyXhr.status,
|
|
1013
|
+
responseHeaders: parseHeaders(ah.proxyXhr.getAllResponseHeaders()),
|
|
1014
|
+
};
|
|
1015
|
+
const tempValues = {};
|
|
1016
|
+
for (const key of xhrResponses) {
|
|
1017
|
+
try {
|
|
1018
|
+
tempValues[key] = ah.originalXhr[key];
|
|
1019
|
+
} catch (err) {}
|
|
1020
|
+
defineProp(
|
|
1021
|
+
response,
|
|
1022
|
+
key,
|
|
1023
|
+
() => {
|
|
1024
|
+
return (response[key] = tempValues[key]);
|
|
1025
|
+
},
|
|
1026
|
+
(val) => {
|
|
1027
|
+
delete response[key];
|
|
1028
|
+
response[key] = val;
|
|
1029
|
+
}
|
|
1099
1030
|
);
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1031
|
+
}
|
|
1032
|
+
ah.resThenable = new AHRequest(ah.request)
|
|
1033
|
+
.waitForResponseKeys(response)
|
|
1034
|
+
.then(() => {
|
|
1035
|
+
for (const key of xhrResponses) {
|
|
1036
|
+
ah.proxyProps[key] = {
|
|
1037
|
+
get: () => {
|
|
1038
|
+
if (!(key in response)) response[key] = tempValues[key];
|
|
1039
|
+
return response[key];
|
|
1040
|
+
},
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
});
|
|
1044
|
+
}
|
|
1045
|
+
ah.dispatchEvent(e);
|
|
1046
|
+
});
|
|
1047
|
+
xhr.addEventListener("load", (e) => ah.dispatchEvent(e));
|
|
1048
|
+
xhr.addEventListener("loadend", (e) => ah.dispatchEvent(e));
|
|
1049
|
+
for (const evt of xhrAsyncEvents) {
|
|
1050
|
+
const onEvt = "on" + evt;
|
|
1051
|
+
ah.proxyProps[onEvt] = {
|
|
1052
|
+
get: () => ah.proxyEvents[onEvt] || null,
|
|
1053
|
+
set: (val) => ah.addEvent(onEvt, val),
|
|
1054
|
+
};
|
|
1104
1055
|
}
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1056
|
+
for (const method of [
|
|
1057
|
+
"setRequestHeader",
|
|
1058
|
+
"addEventListener",
|
|
1059
|
+
"removeEventListener",
|
|
1060
|
+
"open",
|
|
1061
|
+
"send",
|
|
1062
|
+
]) {
|
|
1063
|
+
ah.proxyProps[method] = { value: ah[method] };
|
|
1111
1064
|
}
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1065
|
+
}
|
|
1066
|
+
toJSON() {} // Converting circular structure to JSON
|
|
1067
|
+
addEvent(type, event) {
|
|
1068
|
+
if (type.startsWith("on")) {
|
|
1069
|
+
this.proxyEvents[type] = typeof event === "function" ? event : null;
|
|
1070
|
+
} else {
|
|
1071
|
+
if (typeof event === "object" && event !== null)
|
|
1072
|
+
event = event.handleEvent;
|
|
1073
|
+
if (typeof event !== "function") return;
|
|
1074
|
+
this.proxyEvents[type] = this.proxyEvents[type] || new Set();
|
|
1075
|
+
this.proxyEvents[type].add(event);
|
|
1118
1076
|
}
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1077
|
+
}
|
|
1078
|
+
removeEvent(type, event) {
|
|
1079
|
+
if (type.startsWith("on")) {
|
|
1080
|
+
this.proxyEvents[type] = null;
|
|
1081
|
+
} else {
|
|
1082
|
+
if (typeof event === "object" && event !== null)
|
|
1083
|
+
event = event.handleEvent;
|
|
1084
|
+
this.proxyEvents[type] && this.proxyEvents[type].delete(event);
|
|
1125
1085
|
}
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
};
|
|
1137
|
-
this.openArgs = args;
|
|
1138
|
-
this.resThenable = new SyncThenable();
|
|
1139
|
-
[
|
|
1140
|
-
"responseURL",
|
|
1141
|
-
"readyState",
|
|
1142
|
-
"status",
|
|
1143
|
-
"statusText",
|
|
1144
|
-
...xhrResponses,
|
|
1145
|
-
].forEach((key) => {
|
|
1146
|
-
delete this.proxyProps[key];
|
|
1086
|
+
}
|
|
1087
|
+
dispatchEvent(e) {
|
|
1088
|
+
e.stopImmediatePropagation = stopImmediatePropagation;
|
|
1089
|
+
defineProp(e, "target", () => this.proxyXhr);
|
|
1090
|
+
defineProp(e, "currentTarget", () => this.proxyXhr);
|
|
1091
|
+
this.proxyEvents[e.type] &&
|
|
1092
|
+
this.proxyEvents[e.type].forEach((fn) => {
|
|
1093
|
+
this.resThenable.then(
|
|
1094
|
+
() => !e.ajaxHooker_isStopped && fn.call(this.proxyXhr, e)
|
|
1095
|
+
);
|
|
1147
1096
|
});
|
|
1148
|
-
|
|
1097
|
+
if (e.ajaxHooker_isStopped) return;
|
|
1098
|
+
const onEvent = this.proxyEvents["on" + e.type];
|
|
1099
|
+
onEvent && this.resThenable.then(onEvent.bind(this.proxyXhr, e));
|
|
1100
|
+
}
|
|
1101
|
+
setRequestHeader(header, value) {
|
|
1102
|
+
this.originalXhr.setRequestHeader(header, value);
|
|
1103
|
+
if (!this.request) return;
|
|
1104
|
+
const headers = this.request.headers;
|
|
1105
|
+
headers[header] =
|
|
1106
|
+
header in headers ? `${headers[header]}, ${value}` : value;
|
|
1107
|
+
}
|
|
1108
|
+
addEventListener(...args) {
|
|
1109
|
+
if (xhrAsyncEvents.includes(args[0])) {
|
|
1110
|
+
this.addEvent(args[0], args[1]);
|
|
1111
|
+
} else {
|
|
1112
|
+
this.originalXhr.addEventListener(...args);
|
|
1149
1113
|
}
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
new AHRequest(request).waitForRequestKeys().then(() => {
|
|
1157
|
-
if (request.abort) {
|
|
1158
|
-
if (typeof request.response === "function") {
|
|
1159
|
-
Object.assign(ah.proxyProps, {
|
|
1160
|
-
responseURL: { value: request.url },
|
|
1161
|
-
readyState: { value: 4 },
|
|
1162
|
-
status: { value: 200 },
|
|
1163
|
-
statusText: { value: "OK" },
|
|
1164
|
-
});
|
|
1165
|
-
xhrAsyncEvents.forEach((evt) =>
|
|
1166
|
-
xhr.dispatchEvent(new Event(evt))
|
|
1167
|
-
);
|
|
1168
|
-
}
|
|
1169
|
-
} else {
|
|
1170
|
-
xhr.open(
|
|
1171
|
-
request.method,
|
|
1172
|
-
request.url,
|
|
1173
|
-
request.async,
|
|
1174
|
-
...ah.openArgs
|
|
1175
|
-
);
|
|
1176
|
-
for (const header in request.headers) {
|
|
1177
|
-
xhr.setRequestHeader(header, request.headers[header]);
|
|
1178
|
-
}
|
|
1179
|
-
xhr.send(request.data);
|
|
1180
|
-
}
|
|
1181
|
-
});
|
|
1114
|
+
}
|
|
1115
|
+
removeEventListener(...args) {
|
|
1116
|
+
if (xhrAsyncEvents.includes(args[0])) {
|
|
1117
|
+
this.removeEvent(args[0], args[1]);
|
|
1118
|
+
} else {
|
|
1119
|
+
this.originalXhr.removeEventListener(...args);
|
|
1182
1120
|
}
|
|
1183
1121
|
}
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1122
|
+
open(method, url, async = true, ...args) {
|
|
1123
|
+
this.request = {
|
|
1124
|
+
type: "xhr",
|
|
1125
|
+
url: url.toString(),
|
|
1126
|
+
method: method.toUpperCase(),
|
|
1127
|
+
abort: false,
|
|
1128
|
+
headers: {},
|
|
1129
|
+
data: null,
|
|
1130
|
+
response: null,
|
|
1131
|
+
async: !!async,
|
|
1132
|
+
};
|
|
1133
|
+
this.openArgs = args;
|
|
1134
|
+
this.resThenable = new SyncThenable();
|
|
1135
|
+
[
|
|
1136
|
+
"responseURL",
|
|
1137
|
+
"readyState",
|
|
1138
|
+
"status",
|
|
1139
|
+
"statusText",
|
|
1140
|
+
...xhrResponses,
|
|
1141
|
+
].forEach((key) => {
|
|
1142
|
+
delete this.proxyProps[key];
|
|
1143
|
+
});
|
|
1144
|
+
return this.originalXhr.open(method, url, async, ...args);
|
|
1190
1145
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
const init = {};
|
|
1199
|
-
if (getType(url) === "[object Request]") {
|
|
1200
|
-
for (const prop of fetchInitProps) init[prop] = url[prop];
|
|
1201
|
-
if (url.body) init.body = await url.arrayBuffer();
|
|
1202
|
-
url = url.url;
|
|
1203
|
-
}
|
|
1204
|
-
url = url.toString();
|
|
1205
|
-
Object.assign(init, options);
|
|
1206
|
-
init.method = init.method || "GET";
|
|
1207
|
-
init.headers = init.headers || {};
|
|
1208
|
-
const request = {
|
|
1209
|
-
type: "fetch",
|
|
1210
|
-
url: url,
|
|
1211
|
-
method: init.method.toUpperCase(),
|
|
1212
|
-
abort: false,
|
|
1213
|
-
headers: parseHeaders(init.headers),
|
|
1214
|
-
data: init.body,
|
|
1215
|
-
response: null,
|
|
1216
|
-
async: true,
|
|
1217
|
-
};
|
|
1218
|
-
const req = new AHRequest(request);
|
|
1219
|
-
await req.waitForRequestKeys();
|
|
1146
|
+
send(data) {
|
|
1147
|
+
const ah = this;
|
|
1148
|
+
const xhr = ah.originalXhr;
|
|
1149
|
+
const request = ah.request;
|
|
1150
|
+
if (!request) return xhr.send(data);
|
|
1151
|
+
request.data = data;
|
|
1152
|
+
new AHRequest(request).waitForRequestKeys().then(() => {
|
|
1220
1153
|
if (request.abort) {
|
|
1221
1154
|
if (typeof request.response === "function") {
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
await req.waitForResponseKeys(response);
|
|
1228
|
-
const key = fetchResponses.find((k) => k in response);
|
|
1229
|
-
let val = response[key];
|
|
1230
|
-
if (key === "json" && typeof val === "object") {
|
|
1231
|
-
val = catchError(JSON.stringify.bind(JSON), val);
|
|
1232
|
-
}
|
|
1233
|
-
const res = new Response(val, {
|
|
1234
|
-
status: 200,
|
|
1235
|
-
statusText: "OK",
|
|
1155
|
+
Object.assign(ah.proxyProps, {
|
|
1156
|
+
responseURL: { value: request.url },
|
|
1157
|
+
readyState: { value: 4 },
|
|
1158
|
+
status: { value: 200 },
|
|
1159
|
+
statusText: { value: "OK" },
|
|
1236
1160
|
});
|
|
1237
|
-
|
|
1238
|
-
defineProp(res, "url", () => request.url);
|
|
1239
|
-
resolve(res);
|
|
1240
|
-
} else {
|
|
1241
|
-
reject(new DOMException("aborted", "AbortError"));
|
|
1161
|
+
xhrAsyncEvents.forEach((evt) => xhr.dispatchEvent(new Event(evt)));
|
|
1242
1162
|
}
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
init.body = request.data;
|
|
1248
|
-
winAh.realFetch.call(win, request.url, init).then((res) => {
|
|
1249
|
-
if (typeof request.response === "function") {
|
|
1250
|
-
const response = {
|
|
1251
|
-
finalUrl: res.url,
|
|
1252
|
-
status: res.status,
|
|
1253
|
-
responseHeaders: parseHeaders(res.headers),
|
|
1254
|
-
};
|
|
1255
|
-
fetchResponses.forEach(
|
|
1256
|
-
(key) =>
|
|
1257
|
-
(res[key] = function () {
|
|
1258
|
-
if (key in response) return Promise.resolve(response[key]);
|
|
1259
|
-
return resProto[key].call(this).then((val) => {
|
|
1260
|
-
response[key] = val;
|
|
1261
|
-
return req
|
|
1262
|
-
.waitForResponseKeys(response)
|
|
1263
|
-
.then(() => (key in response ? response[key] : val));
|
|
1264
|
-
});
|
|
1265
|
-
})
|
|
1266
|
-
);
|
|
1163
|
+
} else {
|
|
1164
|
+
xhr.open(request.method, request.url, request.async, ...ah.openArgs);
|
|
1165
|
+
for (const header in request.headers) {
|
|
1166
|
+
xhr.setRequestHeader(header, request.headers[header]);
|
|
1267
1167
|
}
|
|
1268
|
-
|
|
1269
|
-
}
|
|
1168
|
+
xhr.send(request.data);
|
|
1169
|
+
}
|
|
1270
1170
|
});
|
|
1271
1171
|
}
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
return res;
|
|
1277
|
-
}
|
|
1278
|
-
winAh = win.__ajaxHooker = winAh || {
|
|
1279
|
-
version,
|
|
1280
|
-
fakeXHR,
|
|
1281
|
-
fakeFetch,
|
|
1282
|
-
fakeFetchClone,
|
|
1283
|
-
realXHR: win.XMLHttpRequest,
|
|
1284
|
-
realFetch: win.fetch,
|
|
1285
|
-
realFetchClone: resProto.clone,
|
|
1286
|
-
hookInsts: new Set(),
|
|
1287
|
-
};
|
|
1288
|
-
if (winAh.version !== version)
|
|
1172
|
+
}
|
|
1173
|
+
function fakeXHR() {
|
|
1174
|
+
const xhr = new winAh.realXHR();
|
|
1175
|
+
if ("__ajaxHooker" in xhr)
|
|
1289
1176
|
console.warn("检测到不同版本的ajaxHooker,可能发生冲突!");
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1177
|
+
xhr.__ajaxHooker = new XhrHooker(xhr);
|
|
1178
|
+
return xhr.__ajaxHooker.proxyXhr;
|
|
1179
|
+
}
|
|
1180
|
+
fakeXHR.prototype = win.XMLHttpRequest.prototype;
|
|
1181
|
+
Object.keys(win.XMLHttpRequest).forEach(
|
|
1182
|
+
(key) => (fakeXHR[key] = win.XMLHttpRequest[key])
|
|
1183
|
+
);
|
|
1184
|
+
function fakeFetch(url, options = {}) {
|
|
1185
|
+
if (!url) return winAh.realFetch.call(win, url, options);
|
|
1186
|
+
return new Promise(async (resolve, reject) => {
|
|
1187
|
+
const init = {};
|
|
1188
|
+
if (getType(url) === "[object Request]") {
|
|
1189
|
+
for (const prop of fetchInitProps) init[prop] = url[prop];
|
|
1190
|
+
if (url.body) init.body = await url.arrayBuffer();
|
|
1191
|
+
url = url.url;
|
|
1192
|
+
}
|
|
1193
|
+
url = url.toString();
|
|
1194
|
+
Object.assign(init, options);
|
|
1195
|
+
init.method = init.method || "GET";
|
|
1196
|
+
init.headers = init.headers || {};
|
|
1197
|
+
const request = {
|
|
1198
|
+
type: "fetch",
|
|
1199
|
+
url: url,
|
|
1200
|
+
method: init.method.toUpperCase(),
|
|
1201
|
+
abort: false,
|
|
1202
|
+
headers: parseHeaders(init.headers),
|
|
1203
|
+
data: init.body,
|
|
1204
|
+
response: null,
|
|
1205
|
+
async: true,
|
|
1206
|
+
};
|
|
1207
|
+
const req = new AHRequest(request);
|
|
1208
|
+
await req.waitForRequestKeys();
|
|
1209
|
+
if (request.abort) {
|
|
1210
|
+
if (typeof request.response === "function") {
|
|
1211
|
+
const response = {
|
|
1212
|
+
finalUrl: request.url,
|
|
1213
|
+
status: 200,
|
|
1214
|
+
responseHeaders: {},
|
|
1215
|
+
};
|
|
1216
|
+
await req.waitForResponseKeys(response);
|
|
1217
|
+
const key = fetchResponses.find((k) => k in response);
|
|
1218
|
+
let val = response[key];
|
|
1219
|
+
if (key === "json" && typeof val === "object") {
|
|
1220
|
+
val = catchError(JSON.stringify.bind(JSON), val);
|
|
1221
|
+
}
|
|
1222
|
+
const res = new Response(val, {
|
|
1223
|
+
status: 200,
|
|
1224
|
+
statusText: "OK",
|
|
1225
|
+
});
|
|
1226
|
+
defineProp(res, "type", () => "basic");
|
|
1227
|
+
defineProp(res, "url", () => request.url);
|
|
1228
|
+
resolve(res);
|
|
1229
|
+
} else {
|
|
1230
|
+
reject(new DOMException("aborted", "AbortError"));
|
|
1303
1231
|
}
|
|
1304
|
-
return
|
|
1232
|
+
return;
|
|
1305
1233
|
}
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1234
|
+
init.method = request.method;
|
|
1235
|
+
init.headers = request.headers;
|
|
1236
|
+
init.body = request.data;
|
|
1237
|
+
winAh.realFetch.call(win, request.url, init).then((res) => {
|
|
1238
|
+
if (typeof request.response === "function") {
|
|
1239
|
+
const response = {
|
|
1240
|
+
finalUrl: res.url,
|
|
1241
|
+
status: res.status,
|
|
1242
|
+
responseHeaders: parseHeaders(res.headers),
|
|
1243
|
+
};
|
|
1244
|
+
fetchResponses.forEach(
|
|
1245
|
+
(key) =>
|
|
1246
|
+
(res[key] = function () {
|
|
1247
|
+
if (key in response) return Promise.resolve(response[key]);
|
|
1248
|
+
return resProto[key].call(this).then((val) => {
|
|
1249
|
+
response[key] = val;
|
|
1250
|
+
return req
|
|
1251
|
+
.waitForResponseKeys(response)
|
|
1252
|
+
.then(() => (key in response ? response[key] : val));
|
|
1253
|
+
});
|
|
1254
|
+
})
|
|
1255
|
+
);
|
|
1313
1256
|
}
|
|
1314
|
-
|
|
1257
|
+
resolve(res);
|
|
1258
|
+
}, reject);
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1261
|
+
function fakeFetchClone() {
|
|
1262
|
+
const descriptors = Object.getOwnPropertyDescriptors(this);
|
|
1263
|
+
const res = winAh.realFetchClone.call(this);
|
|
1264
|
+
Object.defineProperties(res, descriptors);
|
|
1265
|
+
return res;
|
|
1266
|
+
}
|
|
1267
|
+
winAh = win.__ajaxHooker = winAh || {
|
|
1268
|
+
version,
|
|
1269
|
+
fakeXHR,
|
|
1270
|
+
fakeFetch,
|
|
1271
|
+
fakeFetchClone,
|
|
1272
|
+
realXHR: win.XMLHttpRequest,
|
|
1273
|
+
realFetch: win.fetch,
|
|
1274
|
+
realFetchClone: resProto.clone,
|
|
1275
|
+
hookInsts: new Set(),
|
|
1276
|
+
};
|
|
1277
|
+
if (winAh.version !== version)
|
|
1278
|
+
console.warn("检测到不同版本的ajaxHooker,可能发生冲突!");
|
|
1279
|
+
win.XMLHttpRequest = winAh.fakeXHR;
|
|
1280
|
+
win.fetch = winAh.fakeFetch;
|
|
1281
|
+
resProto.clone = winAh.fakeFetchClone;
|
|
1282
|
+
winAh.hookInsts.add(hookInst);
|
|
1283
|
+
// 针对头条、抖音 secsdk.umd.js 的兼容性处理
|
|
1284
|
+
class AHFunction extends Function {
|
|
1285
|
+
call(thisArg, ...args) {
|
|
1286
|
+
if (
|
|
1287
|
+
thisArg &&
|
|
1288
|
+
thisArg.__ajaxHooker &&
|
|
1289
|
+
thisArg.__ajaxHooker.proxyXhr === thisArg
|
|
1290
|
+
) {
|
|
1291
|
+
thisArg = thisArg.__ajaxHooker.originalXhr;
|
|
1315
1292
|
}
|
|
1293
|
+
return Reflect.apply(this, thisArg, args);
|
|
1316
1294
|
}
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
);
|
|
1326
|
-
Object.setPrototypeOf(
|
|
1327
|
-
csrf.nativeXMLHttpRequestSend,
|
|
1328
|
-
AHFunction.prototype
|
|
1329
|
-
);
|
|
1295
|
+
apply(thisArg, args) {
|
|
1296
|
+
if (
|
|
1297
|
+
thisArg &&
|
|
1298
|
+
thisArg.__ajaxHooker &&
|
|
1299
|
+
thisArg.__ajaxHooker.proxyXhr === thisArg
|
|
1300
|
+
) {
|
|
1301
|
+
thisArg = thisArg.__ajaxHooker.originalXhr;
|
|
1302
|
+
}
|
|
1303
|
+
return Reflect.apply(this, thisArg, args || []);
|
|
1330
1304
|
}
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1305
|
+
}
|
|
1306
|
+
function hookSecsdk(csrf) {
|
|
1307
|
+
Object.setPrototypeOf(
|
|
1308
|
+
csrf.nativeXMLHttpRequestSetRequestHeader,
|
|
1309
|
+
AHFunction.prototype
|
|
1310
|
+
);
|
|
1311
|
+
Object.setPrototypeOf(csrf.nativeXMLHttpRequestOpen, AHFunction.prototype);
|
|
1312
|
+
Object.setPrototypeOf(csrf.nativeXMLHttpRequestSend, AHFunction.prototype);
|
|
1313
|
+
}
|
|
1314
|
+
if (win.secsdk) {
|
|
1315
|
+
if (win.secsdk.csrf && win.secsdk.csrf.nativeXMLHttpRequestOpen)
|
|
1316
|
+
hookSecsdk(win.secsdk.csrf);
|
|
1317
|
+
} else {
|
|
1318
|
+
defineProp(win, "secsdk", emptyFn, (secsdk) => {
|
|
1319
|
+
delete win.secsdk;
|
|
1320
|
+
win.secsdk = secsdk;
|
|
1321
|
+
defineProp(secsdk, "csrf", emptyFn, (csrf) => {
|
|
1322
|
+
delete secsdk.csrf;
|
|
1323
|
+
secsdk.csrf = csrf;
|
|
1324
|
+
if (csrf.nativeXMLHttpRequestOpen) hookSecsdk(csrf);
|
|
1343
1325
|
});
|
|
1344
|
-
}
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
}
|
|
1364
|
-
}
|
|
1365
|
-
}
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
return {
|
|
1329
|
+
hook: (fn) => hookInst.hookFns.push(fn),
|
|
1330
|
+
filter: (arr) => {
|
|
1331
|
+
if (Array.isArray(arr)) hookInst.filters = arr;
|
|
1332
|
+
},
|
|
1333
|
+
protect: () => {
|
|
1334
|
+
readonly(win, "XMLHttpRequest", winAh.fakeXHR);
|
|
1335
|
+
readonly(win, "fetch", winAh.fakeFetch);
|
|
1336
|
+
readonly(resProto, "clone", winAh.fakeFetchClone);
|
|
1337
|
+
},
|
|
1338
|
+
unhook: () => {
|
|
1339
|
+
winAh.hookInsts.delete(hookInst);
|
|
1340
|
+
if (!winAh.hookInsts.size) {
|
|
1341
|
+
writable(win, "XMLHttpRequest", winAh.realXHR);
|
|
1342
|
+
writable(win, "fetch", winAh.realFetch);
|
|
1343
|
+
writable(resProto, "clone", winAh.realFetchClone);
|
|
1344
|
+
delete win.__ajaxHooker;
|
|
1345
|
+
}
|
|
1346
|
+
},
|
|
1347
|
+
};
|
|
1366
1348
|
};
|
|
1367
1349
|
|
|
1368
1350
|
// ==UserScript==
|
|
@@ -2066,14 +2048,14 @@
|
|
|
2066
2048
|
const option = menuOption[index];
|
|
2067
2049
|
this.MenuHandle.$data.data.push({
|
|
2068
2050
|
data: option,
|
|
2069
|
-
id:
|
|
2051
|
+
id: void 0,
|
|
2070
2052
|
});
|
|
2071
2053
|
}
|
|
2072
2054
|
}
|
|
2073
2055
|
else {
|
|
2074
2056
|
this.MenuHandle.$data.data.push({
|
|
2075
2057
|
data: menuOption,
|
|
2076
|
-
id:
|
|
2058
|
+
id: void 0,
|
|
2077
2059
|
});
|
|
2078
2060
|
}
|
|
2079
2061
|
}
|
|
@@ -3216,13 +3198,13 @@
|
|
|
3216
3198
|
status: fetchResponse.status,
|
|
3217
3199
|
statusText: fetchResponse.statusText,
|
|
3218
3200
|
// @ts-ignore
|
|
3219
|
-
response:
|
|
3201
|
+
response: void 0,
|
|
3220
3202
|
responseFetchHeaders: fetchResponse.headers,
|
|
3221
3203
|
responseHeaders: "",
|
|
3222
3204
|
// @ts-ignore
|
|
3223
|
-
responseText:
|
|
3205
|
+
responseText: void 0,
|
|
3224
3206
|
responseType: option.responseType,
|
|
3225
|
-
responseXML:
|
|
3207
|
+
responseXML: void 0,
|
|
3226
3208
|
};
|
|
3227
3209
|
Object.assign(httpxResponse, option.context || {});
|
|
3228
3210
|
// 把headers转为字符串
|
|
@@ -3334,30 +3316,30 @@
|
|
|
3334
3316
|
* 默认配置
|
|
3335
3317
|
*/
|
|
3336
3318
|
#defaultRequestOption = {
|
|
3337
|
-
url:
|
|
3319
|
+
url: void 0,
|
|
3338
3320
|
timeout: 5000,
|
|
3339
3321
|
async: false,
|
|
3340
|
-
responseType:
|
|
3341
|
-
headers:
|
|
3342
|
-
data:
|
|
3343
|
-
redirect:
|
|
3344
|
-
cookie:
|
|
3345
|
-
cookiePartition:
|
|
3346
|
-
binary:
|
|
3347
|
-
nocache:
|
|
3348
|
-
revalidate:
|
|
3349
|
-
context:
|
|
3350
|
-
overrideMimeType:
|
|
3351
|
-
anonymous:
|
|
3352
|
-
fetch:
|
|
3353
|
-
fetchInit:
|
|
3322
|
+
responseType: void 0,
|
|
3323
|
+
headers: void 0,
|
|
3324
|
+
data: void 0,
|
|
3325
|
+
redirect: void 0,
|
|
3326
|
+
cookie: void 0,
|
|
3327
|
+
cookiePartition: void 0,
|
|
3328
|
+
binary: void 0,
|
|
3329
|
+
nocache: void 0,
|
|
3330
|
+
revalidate: void 0,
|
|
3331
|
+
context: void 0,
|
|
3332
|
+
overrideMimeType: void 0,
|
|
3333
|
+
anonymous: void 0,
|
|
3334
|
+
fetch: void 0,
|
|
3335
|
+
fetchInit: void 0,
|
|
3354
3336
|
allowInterceptConfig: {
|
|
3355
3337
|
beforeRequest: true,
|
|
3356
3338
|
afterResponseSuccess: true,
|
|
3357
3339
|
afterResponseError: true,
|
|
3358
3340
|
},
|
|
3359
|
-
user:
|
|
3360
|
-
password:
|
|
3341
|
+
user: void 0,
|
|
3342
|
+
password: void 0,
|
|
3361
3343
|
onabort() { },
|
|
3362
3344
|
onerror() { },
|
|
3363
3345
|
ontimeout() { },
|
|
@@ -3369,7 +3351,7 @@
|
|
|
3369
3351
|
/**
|
|
3370
3352
|
* `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
|
|
3371
3353
|
*/
|
|
3372
|
-
baseURL:
|
|
3354
|
+
baseURL: void 0,
|
|
3373
3355
|
/**
|
|
3374
3356
|
* 当前使用请求时,输出请求的配置,一般用于DEBUG|DEV
|
|
3375
3357
|
*/
|
|
@@ -3774,7 +3756,7 @@
|
|
|
3774
3756
|
success: false,
|
|
3775
3757
|
code: that.#statusCode.getFailed.code,
|
|
3776
3758
|
msg: that.#statusCode.getFailed.msg,
|
|
3777
|
-
data:
|
|
3759
|
+
data: void 0,
|
|
3778
3760
|
});
|
|
3779
3761
|
}
|
|
3780
3762
|
else {
|
|
@@ -3784,7 +3766,7 @@
|
|
|
3784
3766
|
let result = target.result;
|
|
3785
3767
|
/* result 返回的是 {key: string, value: any} */
|
|
3786
3768
|
/* 键值对存储 */
|
|
3787
|
-
let data = result ? result.value :
|
|
3769
|
+
let data = result ? result.value : void 0;
|
|
3788
3770
|
if (data == null) {
|
|
3789
3771
|
resolve({
|
|
3790
3772
|
success: true,
|
|
@@ -3811,7 +3793,7 @@
|
|
|
3811
3793
|
success: false,
|
|
3812
3794
|
code: that.#statusCode.getFailed.code,
|
|
3813
3795
|
msg: that.#statusCode.getFailed.msg,
|
|
3814
|
-
data:
|
|
3796
|
+
data: void 0,
|
|
3815
3797
|
event: event,
|
|
3816
3798
|
});
|
|
3817
3799
|
};
|
|
@@ -3961,7 +3943,7 @@
|
|
|
3961
3943
|
#flag = false;
|
|
3962
3944
|
#delayTime = 0;
|
|
3963
3945
|
#callback;
|
|
3964
|
-
#timeId =
|
|
3946
|
+
#timeId = void 0;
|
|
3965
3947
|
lock;
|
|
3966
3948
|
unlock;
|
|
3967
3949
|
run;
|
|
@@ -4384,7 +4366,7 @@
|
|
|
4384
4366
|
*/
|
|
4385
4367
|
getStartsWith(key) {
|
|
4386
4368
|
let allKeys = this.keys();
|
|
4387
|
-
let result =
|
|
4369
|
+
let result = void 0;
|
|
4388
4370
|
for (const keyName of allKeys) {
|
|
4389
4371
|
if (String(keyName).startsWith(String(key))) {
|
|
4390
4372
|
result = this.get(keyName);
|
|
@@ -4399,7 +4381,7 @@
|
|
|
4399
4381
|
* @param val 值,默认为""
|
|
4400
4382
|
*/
|
|
4401
4383
|
set(key, val) {
|
|
4402
|
-
if (key ===
|
|
4384
|
+
if (key === void 0) {
|
|
4403
4385
|
throw new Error("Utils.Dictionary().set 参数 key 不能为空");
|
|
4404
4386
|
}
|
|
4405
4387
|
Reflect.set(this.items, key, val);
|
|
@@ -5614,7 +5596,7 @@
|
|
|
5614
5596
|
this.windowApi = new WindowApi(option);
|
|
5615
5597
|
}
|
|
5616
5598
|
/** 版本号 */
|
|
5617
|
-
version = "2025.6.
|
|
5599
|
+
version = "2025.6.26";
|
|
5618
5600
|
addStyle(cssText) {
|
|
5619
5601
|
if (typeof cssText !== "string") {
|
|
5620
5602
|
throw new Error("Utils.addStyle 参数cssText 必须为String类型");
|
|
@@ -5698,7 +5680,7 @@
|
|
|
5698
5680
|
* ajax劫持库,支持xhr和fetch劫持。
|
|
5699
5681
|
* + 来源:https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
|
|
5700
5682
|
* + 作者:cxxjackie
|
|
5701
|
-
* + 版本:1.4.
|
|
5683
|
+
* + 版本:1.4.6
|
|
5702
5684
|
* + 旧版本:1.2.4
|
|
5703
5685
|
* + 文档:https://scriptcat.org/zh-CN/script-show-page/637/
|
|
5704
5686
|
* @param useOldVersion 是否使用旧版本,默认false
|
|
@@ -5708,7 +5690,7 @@
|
|
|
5708
5690
|
return AjaxHooker1_2_4();
|
|
5709
5691
|
}
|
|
5710
5692
|
else {
|
|
5711
|
-
return
|
|
5693
|
+
return ajaxHooker();
|
|
5712
5694
|
}
|
|
5713
5695
|
};
|
|
5714
5696
|
canvasClickByPosition(canvasElement, clientX = 0, clientY = 0, view = globalThis) {
|
|
@@ -7269,36 +7251,36 @@
|
|
|
7269
7251
|
* + true 监听以 target 为根节点的整个子树。包括子树中所有节点的属性,而不仅仅是针对 target
|
|
7270
7252
|
* + false (默认) 不生效
|
|
7271
7253
|
*/
|
|
7272
|
-
subtree:
|
|
7254
|
+
subtree: void 0,
|
|
7273
7255
|
/**
|
|
7274
7256
|
* + true 监听 target 节点中发生的节点的新增与删除(同时,如果 subtree 为 true,会针对整个子树生效)
|
|
7275
7257
|
* + false (默认) 不生效
|
|
7276
7258
|
*/
|
|
7277
|
-
childList:
|
|
7259
|
+
childList: void 0,
|
|
7278
7260
|
/**
|
|
7279
7261
|
* + true 观察所有监听的节点属性值的变化。默认值为 true,当声明了 attributeFilter 或 attributeOldValue
|
|
7280
7262
|
* + false (默认) 不生效
|
|
7281
7263
|
*/
|
|
7282
|
-
attributes:
|
|
7264
|
+
attributes: void 0,
|
|
7283
7265
|
/**
|
|
7284
7266
|
* 一个用于声明哪些属性名会被监听的数组。如果不声明该属性,所有属性的变化都将触发通知
|
|
7285
7267
|
*/
|
|
7286
|
-
attributeFilter:
|
|
7268
|
+
attributeFilter: void 0,
|
|
7287
7269
|
/**
|
|
7288
7270
|
* + true 记录上一次被监听的节点的属性变化;可查阅 MutationObserver 中的 Monitoring attribute values 了解关于观察属性变化和属性值记录的详情
|
|
7289
7271
|
* + false (默认) 不生效
|
|
7290
7272
|
*/
|
|
7291
|
-
attributeOldValue:
|
|
7273
|
+
attributeOldValue: void 0,
|
|
7292
7274
|
/**
|
|
7293
7275
|
* + true 监听声明的 target 节点上所有字符的变化。默认值为 true,如果声明了 characterDataOldValue
|
|
7294
7276
|
* + false (默认) 不生效
|
|
7295
7277
|
*/
|
|
7296
|
-
characterData:
|
|
7278
|
+
characterData: void 0,
|
|
7297
7279
|
/**
|
|
7298
7280
|
* + true 记录前一个被监听的节点中发生的文本变化
|
|
7299
7281
|
* + false (默认) 不生效
|
|
7300
7282
|
*/
|
|
7301
|
-
characterDataOldValue:
|
|
7283
|
+
characterDataOldValue: void 0,
|
|
7302
7284
|
},
|
|
7303
7285
|
immediate: false,
|
|
7304
7286
|
};
|
|
@@ -7874,7 +7856,7 @@
|
|
|
7874
7856
|
}
|
|
7875
7857
|
return new Promise((resolve) => {
|
|
7876
7858
|
UtilsContext.workerSetTimeout(() => {
|
|
7877
|
-
resolve(
|
|
7859
|
+
resolve(void 0);
|
|
7878
7860
|
}, delayTime);
|
|
7879
7861
|
});
|
|
7880
7862
|
}
|
|
@@ -8217,7 +8199,7 @@
|
|
|
8217
8199
|
}
|
|
8218
8200
|
waitNode(...args) {
|
|
8219
8201
|
// 过滤掉undefined
|
|
8220
|
-
args = args.filter((arg) => arg !==
|
|
8202
|
+
args = args.filter((arg) => arg !== void 0);
|
|
8221
8203
|
let UtilsContext = this;
|
|
8222
8204
|
// 选择器
|
|
8223
8205
|
let selector = args[0];
|
|
@@ -8306,7 +8288,7 @@
|
|
|
8306
8288
|
}
|
|
8307
8289
|
waitAnyNode(...args) {
|
|
8308
8290
|
// 过滤掉undefined
|
|
8309
|
-
args = args.filter((arg) => arg !==
|
|
8291
|
+
args = args.filter((arg) => arg !== void 0);
|
|
8310
8292
|
let UtilsContext = this;
|
|
8311
8293
|
// 选择器
|
|
8312
8294
|
let selectorList = args[0];
|
|
@@ -8362,7 +8344,7 @@
|
|
|
8362
8344
|
}
|
|
8363
8345
|
waitNodeList(...args) {
|
|
8364
8346
|
// 过滤掉undefined
|
|
8365
|
-
args = args.filter((arg) => arg !==
|
|
8347
|
+
args = args.filter((arg) => arg !== void 0);
|
|
8366
8348
|
let UtilsContext = this;
|
|
8367
8349
|
// 选择器数组
|
|
8368
8350
|
let selector = args[0];
|
|
@@ -8449,7 +8431,7 @@
|
|
|
8449
8431
|
}
|
|
8450
8432
|
waitAnyNodeList(...args) {
|
|
8451
8433
|
// 过滤掉undefined
|
|
8452
|
-
args = args.filter((arg) => arg !==
|
|
8434
|
+
args = args.filter((arg) => arg !== void 0);
|
|
8453
8435
|
let UtilsContext = this;
|
|
8454
8436
|
// 选择器数组
|
|
8455
8437
|
let selectorList = args[0];
|