Major 发表于 2022-12-31 13:49:45

油猴脚本劫持截获ajax数据json数据并将修改后的内容返回

本帖最后由 Major 于 2022-12-31 13:53 编辑

> 本帖最后由 Major 于 2022-12-31 13:52 编辑


我想截获一个 ajax json数据,修改内容后再将其返回。
搬运了一段代码,貌似可以截获。但是浏览器会一直停留在加载状态,无法将截获的数据再返回。
能否帮助修改一下,或者提供一个完整试例 能够套用或者参考的。感谢!

```
// ==UserScript==
// @name         劫持并修改Json数据,讲修改后的结果返回
// @namespace    修改json数据并返回
// @version      0.1.0
// @descriptiontry to take over the world!
// @author       You
// @match      http*://*/show?id*
// @run-at       document-start
// ==/UserScript==


function hookJson(){
    const xhrOpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function() {
      if (arguments == '/api/show') {
            console.log('成功识别到了目标网址',arguments)
            const xhr = this;
            let response = 'responseText'   //responseTextresponse
            const getter = Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype, response).get;
            Object.defineProperty(xhr, response, {
                get: () => {
                var result = getter.call(xhr);
                console.log(result)
                //这里可以修改result
                result = '{"data":"我是修改后的数据"}';
                console.log(result)
                return result;
                }
            });
      }else{
            console.log('未识别到目标网址!',arguments)
      };
      return xhrOpen.apply(xhr, arguments);
    };
};


(function() {
    hookJson();
})();
```
!(data/attachment/forum/202212/31/135215f6pj4s9as4olj4jp.png)

cxxjackie 发表于 2022-12-31 13:49:46

this指向错误。const是块级作用域,`const xhr = this`这句写在了if语句块内,导致if结束后xhr的定义就没了,最后那句实际上变成了:
```
return xhrOpen.apply(undefined, arguments);
```
后续请求因此丢失了xhr引用,这是报错的原因。解决方法:将`const xhr = this;`提升到if之上即可。

李恒道 发表于 2022-12-31 14:22:25

会不会是因为 result = '{"data":"我是修改后的数据"}';返回的是字符串格式导致的
原来的可能格式跟这个不一样?
这个要具体调试的
可以追到错误点看看什么原因导致的运行错误
如果是xhr劫持代码导致的可以反馈一下
后续再修补
也可以尝试一下c大的库
https://bbs.tampermonkey.net.cn/forum.php?mod=viewthread&tid=3284&highlight=ajax

脚本体验师001 发表于 2022-12-31 18:56:08

      obj.tidyPageFileList = function () {
            (function(open) {
                XMLHttpRequest.prototype.open = function() {
                  if (!this._hooked) {
                        this._hooked = true;
                        setupHook(this);
                  }
                  open.apply(this, arguments);
                }
            })(XMLHttpRequest.prototype.open);

            function setupHook(xhr) {
                var f = ["aac", "ac3", "amr", "flac", "m4a", "mp2", "mp3", "ogg", "ra", "wav", "wma"]
                , m = ["3gp", "avi", "flv", "mkv", "mov", "mp4", "mpg", "rmvb", "webm", "wmv", "rm", "mpeg"];
                (function setup() {
                  Object.defineProperty(xhr, "response", {
                        get: function () {
                            delete xhr.response;
                            var responseURL = xhr.responseURL, response = xhr.response;
                            if (responseURL.includes("/file/list") || responseURL.includes("/file/search")) {
                              response && response.items && response.items.forEach(function (item) {
                                    if (item.category == "video") {
                                        if (!m.includes(item.file_extension)) {
                                          item.file_extension = "mp4";
                                        }
                                    }
                                    else if (item.category == "audio") {
                                        if (!f.includes(item.file_extension)) {
                                          item.file_extension = "mp3";
                                        }
                                    }

                                    if (item.punish_flag) {
                                        item.punish_flag = 0;
                                    }
                              });
                            }
                            else if (responseURL.includes("/file/get")) {
                              if (response && response.category == "video") {
                                    if (!m.includes(response.file_extension)) {
                                        response.file_extension = "mp4";
                                    }
                              }
                            }
                            setup();
                            return response;
                        },
                        configurable: true
                  });
                })();
            }
      };
这是一段验证过可以正常使用的代码,但推荐也可以尝试一下c大的库
https://bbs.tampermonkey.net.cn/forum.php?mod=viewthread&tid=3284&highlight=ajax

Major 发表于 2023-1-1 11:27:31

cxxjackie 发表于 2022-12-31 20:08
this指向错误。const是块级作用域,`const xhr = this`这句写在了if语句块内,导致if结束后xhr的定义就 ...

你这个非常可以,顺利执行了,感谢!!!!
页: [1]
查看完整版本: 油猴脚本劫持截获ajax数据json数据并将修改后的内容返回