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