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