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