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