hookFetch

only hookFetch

目前为 2023-05-04 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/465483/1185275/hookFetch.js

  1. (() => {
  2. var unsafeWindow = window.unsafeWindow || document.defaultView || window;
  3. if (unsafeWindow['__hookRequest__'] != null) {
  4. return;
  5. }
  6. var globalVariable = new Map();
  7. var FetchMapList = new Map();
  8. var XhrMapList = new Map();
  9.  
  10. function deliveryTask(callbackList, _object, period) {
  11. let newObject = _object;
  12. for (let i = 0; i < callbackList.length; i++) {
  13. let tempObject = null;
  14. try {
  15. tempObject = callbackList[i](newObject, period);
  16. } catch (e) {
  17. new Error(e);
  18. }
  19. if (tempObject == null) {
  20. continue;
  21. }
  22. newObject = tempObject;
  23. }
  24. return newObject;
  25. }
  26.  
  27. function hookFetch() {
  28. const originalFetch = unsafeWindow.fetch;
  29. globalVariable.set('Fetch', originalFetch);
  30. unsafeWindow.fetch = (...args) => {
  31. let U = args[0];
  32. if (U.indexOf('http') == -1) {
  33. if (U[0] !== '/') {
  34. let pathname = new URL(location.href).pathname;
  35. U = pathname + U;
  36. }
  37. U = location.origin + U;
  38. }
  39. let apply = null;
  40. (() => {
  41. let url = new URL(U),
  42. pathname = url.pathname,
  43. callback = FetchMapList.get(pathname);
  44. if (callback == null) return;
  45. if (callback.length === 0) return;
  46. let newObject = deliveryTask(callback, { args }, 'preRequest');
  47. if (newObject && newObject.args) {
  48. args = newObject.args;
  49. }
  50. apply = originalFetch.apply(this, args);
  51. apply.then((response) => {
  52. let text = response.text,
  53. json = response.json;
  54. response.text = () => {
  55. return text.apply(response).then((text) => {
  56. let _object = deliveryTask(callback, { text, args }, 'done');
  57. if (_object && _object.text) {
  58. text = _object.text;
  59. }
  60. return text;
  61. });
  62. };
  63. response.json = () => {
  64. return json.apply(response).then((json) => {
  65. let text = JSON.stringify(json);
  66. let _object = deliveryTask(callback, { text, args }, 'done');
  67. if (_object && _object.text) {
  68. text = _object.text;
  69. return JSON.parse(text);
  70. }
  71. return json;
  72. });
  73. };
  74. });
  75. })();
  76. if (apply == null) {
  77. apply = originalFetch.apply(this, args);
  78. }
  79. return apply;
  80. };
  81. }
  82.  
  83. function hookXhr() {
  84. const XHRProxy = new Proxy(unsafeWindow.XMLHttpRequest, {
  85. construct(target, args) {
  86. const xhr = new target(...args);
  87. const originalOpen = xhr.open;
  88. const originalSend = xhr.send;
  89. xhr.open = function () {
  90. return originalOpen.apply(xhr, arguments);
  91. };
  92. xhr.send = function () {
  93. let o = function (args) {
  94. return originalSend.apply(xhr, args);
  95. };
  96. let args = arguments;
  97. let U = xhr.responseURL;
  98. if (U.indexOf('http') == -1) {
  99. if (U[0] !== '/') {
  100. let pathname = new URL(location.href).pathname;
  101. U = pathname + U;
  102. }
  103. U = location.origin + U;
  104. }
  105. let pathname = new URL(U).pathname;
  106. let callback = XhrMapList.get(pathname);
  107. if (callback == null) return o(args);
  108. if (callback.length === 0) return o(args);
  109. let newObject = deliveryTask(callback, { args }, 'preRequest');
  110. if (newObject && newObject.args) {
  111. args = newObject.args;
  112. }
  113. const onReadyStateChangeOriginal = xhr.onreadystatechange;
  114. xhr.onreadystatechange = function () {
  115. if (xhr.readyState === 4 && xhr.status === 200) {
  116. let text = xhr.responseText;
  117. let newObject = deliveryTask(callback, { text, args }, 'done');
  118. if (newObject && newObject.text) {
  119. xhr.responseText = newObject.text;
  120. }
  121. }
  122. onReadyStateChangeOriginal && onReadyStateChangeOriginal.apply(xhr, args);
  123. };
  124. return o(args);
  125. };
  126. return xhr;
  127. }
  128. });
  129. unsafeWindow.XMLHttpRequest = XHRProxy;
  130. }
  131.  
  132. (async () => {
  133. hookFetch();
  134. })();
  135. (async () => {
  136. hookXhr();
  137. })();
  138.  
  139. unsafeWindow['__hookRequest__'] = {
  140. FetchCallback: {
  141. add: (pathname, callback) => {
  142. let list = FetchMapList.get(pathname) || (FetchMapList.set(pathname, []), FetchMapList.get(pathname));
  143. list.push(callback);
  144. let index = list.length;
  145. return index;
  146. },
  147. del: (pathname, index) => {
  148. try {
  149. let list = FetchMapList.get(pathname);
  150. if (list == null) return false;
  151. list.splice(index - 1, 1);
  152. } catch (e) {
  153. new Error(e);
  154. return false;
  155. }
  156. return true;
  157. }
  158. },
  159. XhrCallback: {
  160. add: (pathname, callback) => {
  161. let list = XhrMapList.get(pathname) || (XhrMapList.set(pathname, []), XhrMapList.get(pathname));
  162. list.push(callback);
  163. let index = list.length;
  164. return index;
  165. },
  166. del: (pathname, index) => {
  167. try {
  168. let list = XhrMapList.get(pathname);
  169. if (list == null) return false;
  170. list.splice(index - 1, 1);
  171. } catch (e) {
  172. new Error(e);
  173. return false;
  174. }
  175. return true;
  176. }
  177. },
  178. globalVariable: {
  179. get: (key) => {
  180. return globalVariable.get(key);
  181. },
  182. getAll: () => {
  183. return globalVariable.entries();
  184. },
  185. set: (key, value) => {
  186. globalVariable.set(key, value);
  187. },
  188. getOrDrfault: (key, defaultValue) => {
  189. return globalVariable.get(key) || defaultValue;
  190. }
  191. }
  192. };
  193. })();