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