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