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