清清清 发表于 2023-2-15 16:19:02

本帖最后由 清清清 于 2023-2-15 16:21 编辑

李恒道 发表于 2023-2-15 15:39
而且这个是监听的,应该用修改的
目前场景是,修改指定接口返回数据,数据也在其他接口上,如何实现这个功能呢?

目前解决方案,在send函数中发送异步请求(async await 不确定是否成功,对函数未发现影响,也可能是返回速度快{:4_89:}),在load函数中可以拿到结果。但是send函数中没有请求地址。所以重写了open函数。

不知道大佬有没有更好的处理方案。

以下是代码
function asyncPost(url, payload) {
    return new Promise((resolve, reject) => {
      GM_xmlhttpRequest({
      method: "POST",
      url: url,
      headers: { "Content-Type": "application/json" },
      data: JSON.stringify(payload),
      synchronous: true,
      onload: function (response) {
          console.log("asyncPost: " + url);
          resolve(response.responseText);
      },
      });
    });
}

function addXMLRequestCallback(callback) {
    var oldOpen, oldSend, i;
    if (XMLHttpRequest.callbacks) {
      XMLHttpRequest.callbacks.push(callback);
    } else {
      XMLHttpRequest.callbacks = ;

      oldOpen = XMLHttpRequest.prototype.open;
      XMLHttpRequest.prototype.open = function () {
      this.url = arguments;
      return oldOpen.apply(this, arguments);
      };

      oldSend = XMLHttpRequest.prototype.send;
      XMLHttpRequest.prototype.send = async function () {
      for (i = 0; i < XMLHttpRequest.callbacks.length; i++) {
          XMLHttpRequest.callbacks(this);
      }
      this.payload = JSON.parse(arguments);
      if (this.url === "http://127.0.0.1:8080") {
          this.newResponseText = await asyncPost(this.url, this.payload);
      }
      oldSend.apply(this, arguments);
      };
    }
}

addXMLRequestCallback(function (xhr) {
    xhr.addEventListener("load", function () {
      if (this.readyState == 4 && this.status == 200) {
      console.log(this.url)
      if (this.url === "http://127.0.0.1:8080") {
          const resObj = JSON.parse(this.responseText);
          const newResObj = JSON.parse(this.newResponseText);
          Object.defineProperty(this, "responseText", {
            writable: true,
          });
          resObj.data.push(...newResObj.data);
          this.responseText = JSON.stringify(resObj);
      }
      }
    });
});


还有一个小问题,就是每次发送请求都会有一个弹窗,提示是否发送异步请求,这个可以关闭吗。

李恒道 发表于 2023-2-15 16:24:41

清清清 发表于 2023-2-15 16:19
目前场景是,修改指定接口返回数据,数据也在其他接口上,如何实现这个功能呢?

目前解决方案,在send函 ...

如果是需要其他接口数据的情况下
感觉应该考虑直接屏蔽掉原函数的数据了,直接自己发送一遍
然后主动调用回调啥的了
GM_xmlhttpRequest触发弹窗要写connect声明

清清清 发表于 2023-2-15 17:02:15

李恒道 发表于 2023-2-15 16:24
如果是需要其他接口数据的情况下
感觉应该考虑直接屏蔽掉原函数的数据了,直接自己发送一遍
然后主动调用 ...

不用屏蔽原来函数,还需要之前的部分数据。
还有一个场景,需要原接口返回数据作为参数,发给新的接口,目前还无法实现这个功能。

跨域弹窗已解决。

李恒道 发表于 2023-2-15 17:37:19

清清清 发表于 2023-2-15 17:02
不用屏蔽原来函数,还需要之前的部分数据。
还有一个场景,需要原接口返回数据作为参数,发给新的接口, ...
根需要之前数据不冲突的
直接废掉他的发送,自己在里面写新的发送逻辑,这样逻辑都在一个函数里更方便
不然太难控制回调了

清清清 发表于 2023-2-15 18:55:41

李恒道 发表于 2023-2-15 17:37
根需要之前数据不冲突的
直接废掉他的发送,自己在里面写新的发送逻辑,这样逻辑都在一个函数里更方便
不 ...

拦截发送,写新的发送,自己请求和原来的请求 各自发送。两个异步就合成一个异步,统一返回数据是吗。我试试。

如果说我想在原来请求返回数据后,在发送我的请求。最后统一返回给页面进行渲染,这个应该怎么操作呀。

李恒道 发表于 2023-2-15 19:13:33

清清清 发表于 2023-2-15 18:55
拦截发送,写新的发送,自己请求和原来的请求 各自发送。两个异步就合成一个异步,统一返回数据是吗。我 ...
非要这样的话可以试试同步xhr+劫持reponse
用promise是具备污染性的
但是这样搞会冻死住页面
是不推荐这么搞得...

cxxjackie 发表于 2023-2-15 20:56:26

清清清 发表于 2023-2-15 18:55
拦截发送,写新的发送,自己请求和原来的请求 各自发送。两个异步就合成一个异步,统一返回数据是吗。我 ...

试试这个:https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
原理是劫持load等事件延迟触发。
页: 1 2 3 [4]
查看完整版本: [油猴脚本开发指南]XHR劫持的第二种格式