XHS

XML Http Sniffer

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.cn-greasyfork.org/scripts/443537/1041211/XHS.js

  1. // ==UserScript==
  2. // @name XHS
  3. // @license MIT
  4. // @version 1.2
  5. // @description XML Http Sniffer
  6. // @author 0vC4
  7. // @match http://*/*
  8. // @match https://*/*
  9. // @grant none
  10. // @run-at document-start
  11. // @namespace https://greasyfork.org/users/670183
  12. // ==/UserScript==
  13.  
  14.  
  15.  
  16.  
  17.  
  18. const XHS = (() => {
  19. const xhs = window.xhs || {};
  20. if (xhs.xhr) return xhs;
  21. const pipe = (type, ...next) => function() {
  22. for (const hook of xhs.hooks.sort((a, b) => b.priority - a.priority)) {
  23. if (!hook[type]) continue;
  24. if (!arguments) break;
  25. arguments = hook[type].call(this, ...arguments);
  26. }
  27. if (!arguments) return;
  28. next.flat().forEach(func => func.call(this, ...arguments));
  29. };
  30. const proto = XMLHttpRequest.prototype;
  31. xhs.xhr = XMLHttpRequest;
  32. xhs.open = proto.open;
  33. xhs.send = proto.send;
  34. xhs.hooks = [];
  35. xhs.setHook = hook => {
  36. xhs.hooks.push(hook);
  37. return xhs;
  38. };
  39. xhs.setHooks = (...hooks) => {
  40. xhs.hooks.push(...hooks.flat());
  41. return xhs;
  42. };
  43. proto.open = function() {
  44. const [method, url] = arguments;
  45. Object.assign(this, { method, url });
  46. pipe('open', xhs.open).call(this, ...arguments);
  47. };
  48. proto.send = function() {
  49. this._onload = this.onload || (() => 0);
  50. this.onload = function() {
  51. Object.defineProperty(this, 'response', {
  52. enumerable: true,
  53. configurable: true,
  54. writable: true,
  55. value: this.response,
  56. });
  57. pipe('onload', this._onload).call(this, ...arguments);
  58. };
  59. pipe('send', xhs.send).call(this, ...arguments);
  60. };
  61. return xhs;
  62. })();
  63. // 0vC4#7152