上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
1234
返回列表 发新帖
楼主: 李恒道 - 

[油猴脚本开发指南]XHR劫持的第二种格式

[复制链接]
  • TA的每日心情

    2023-2-16 01:48
  • 签到天数: 2 天

    [LV.1]初来乍到

    0

    主题

    12

    回帖

    10

    积分

    助理工程师

    积分
    10
    发表于 2023-2-15 16:19:02 | 显示全部楼层
    本帖最后由 清清清 于 2023-2-15 16:21 编辑
    李恒道 发表于 2023-2-15 15:39
    而且这个是监听的,应该用修改的

    目前场景是,修改指定接口返回数据,数据也在其他接口上,如何实现这个功能呢?

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

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

    以下是代码
    1.   function asyncPost(url, payload) {
    2.     return new Promise((resolve, reject) => {
    3.       GM_xmlhttpRequest({
    4.         method: "POST",
    5.         url: url,
    6.         headers: { "Content-Type": "application/json" },
    7.         data: JSON.stringify(payload),
    8.         synchronous: true,
    9.         onload: function (response) {
    10.           console.log("asyncPost: " + url);
    11.           resolve(response.responseText);
    12.         },
    13.       });
    14.     });
    15.   }

    16.   function addXMLRequestCallback(callback) {
    17.     var oldOpen, oldSend, i;
    18.     if (XMLHttpRequest.callbacks) {
    19.       XMLHttpRequest.callbacks.push(callback);
    20.     } else {
    21.       XMLHttpRequest.callbacks = [callback];

    22.       oldOpen = XMLHttpRequest.prototype.open;
    23.       XMLHttpRequest.prototype.open = function () {
    24.         this.url = arguments[1];
    25.         return oldOpen.apply(this, arguments);
    26.       };

    27.       oldSend = XMLHttpRequest.prototype.send;
    28.       XMLHttpRequest.prototype.send = async function () {
    29.         for (i = 0; i < XMLHttpRequest.callbacks.length; i++) {
    30.           XMLHttpRequest.callbacks[i](this);
    31.         }
    32.         this.payload = JSON.parse(arguments[0]);
    33.         if (this.url === "http://127.0.0.1:8080") {
    34.           this.newResponseText = await asyncPost(this.url, this.payload);
    35.         }
    36.         oldSend.apply(this, arguments);
    37.       };
    38.     }
    39.   }

    40.   addXMLRequestCallback(function (xhr) {
    41.     xhr.addEventListener("load", function () {
    42.       if (this.readyState == 4 && this.status == 200) {
    43.         console.log(this.url)
    44.         if (this.url === "http://127.0.0.1:8080") {
    45.           const resObj = JSON.parse(this.responseText);
    46.           const newResObj = JSON.parse(this.newResponseText);
    47.           Object.defineProperty(this, "responseText", {
    48.             writable: true,
    49.           });
    50.           resObj.data.push(...newResObj.data);
    51.           this.responseText = JSON.stringify(resObj);
    52.         }
    53.       }
    54.     });
    55.   });
    复制代码


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

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5999

    回帖

    6784

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6784

    荣誉开发者喜迎中秋油中2周年生态建设者

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

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

    如果是需要其他接口数据的情况下
    感觉应该考虑直接屏蔽掉原函数的数据了,直接自己发送一遍
    然后主动调用回调啥的了
    GM_xmlhttpRequest触发弹窗要写connect声明
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情

    2023-2-16 01:48
  • 签到天数: 2 天

    [LV.1]初来乍到

    0

    主题

    12

    回帖

    10

    积分

    助理工程师

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

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

    跨域弹窗已解决。
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5999

    回帖

    6784

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6784

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2023-2-15 17:37:19 | 显示全部楼层
    清清清 发表于 2023-2-15 17:02
    不用屏蔽原来函数,还需要之前的部分数据。
    还有一个场景,需要原接口返回数据作为参数,发给新的接口, ...

    根需要之前数据不冲突的
    直接废掉他的发送,自己在里面写新的发送逻辑,这样逻辑都在一个函数里更方便
    不然太难控制回调了

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情

    2023-2-16 01:48
  • 签到天数: 2 天

    [LV.1]初来乍到

    0

    主题

    12

    回帖

    10

    积分

    助理工程师

    积分
    10
    发表于 2023-2-15 18:55:41 | 显示全部楼层
    李恒道 发表于 2023-2-15 17:37
    根需要之前数据不冲突的
    直接废掉他的发送,自己在里面写新的发送逻辑,这样逻辑都在一个函数里更方便
    不 ...

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

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

    使用道具 举报

  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5999

    回帖

    6784

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6784

    荣誉开发者喜迎中秋油中2周年生态建设者

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

    非要这样的话可以试试同步xhr+劫持reponse
    用promise是具备污染性的
    但是这样搞会冻死住页面
    是不推荐这么搞得...
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    883

    回帖

    1381

    积分

    荣誉开发者

    积分
    1381

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

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

    试试这个:https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
    原理是劫持load等事件延迟触发。
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表