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