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

Fetch劫持方式补充

[复制链接]
  • TA的每日心情
    无聊
    2023-11-2 17:37
  • 签到天数: 275 天

    [LV.8]以坛为家I

    111

    主题

    446

    回帖

    961

    积分

    荣誉开发者

    积分
    961

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

    发表于 2023-4-5 10:35:51 | 显示全部楼层 | 阅读模式

    本帖最后由 wwwwwllllk 于 2023-4-5 10:37 编辑

    看了道哥这篇文章的补充吧,避免在学的过程还需要百度其它知识点,感觉自己写的过程涉及到东西太多了,本来是看webpack劫持修改函数的,但是自己在实战的时候发现劫持请求可能更容易达到效果,我们在写脚本的时候其实正常来说不需要学这些东西就可以完成我们的需求,除非就要改变网站原来的逻辑或者请求参数返回结果就需要这样做了。

    文章结合下面这篇文章看,我这里只作补充,把我学习的过程遇到的问题补充一下,也方便自己看方便

    Fetch劫持的第二种方式

    思路

    1.当我们比如要对某一个网站按钮点击触发以后界面弹出一个alert弹框,这个时候正常来说点击一个按钮大多数情况是和后端会产生交互的,这个时候我们就可以通过xhr请求来定位到我们想看的位置。

    实战

    image.png

    image.png

    image.png

    let oldfetch = fetch;
    function fuckfetch() {
        return new Promise((resolve, reject) => {
            oldfetch.apply(this, arguments).then(response => {
                const oldJson = response.json;
                response.json = function() {
                    return new Promise((resolve, reject) => {
                        oldJson.apply(this, arguments).then(result => {
                            console.log(result)
                            alert('收藏成功')
                            resolve(result);
                        });
                    });
                };
                resolve(response);
            });
        });
    }
    window.fetch = fuckfetch;

    image.png

    这个只是简单的实战,从用途来说并没有任何意义,

    我想做的是因为我发现语雀有个bug,反馈了还没解

    决,所以正好尝试,我们实现的效果通过劫持实现当

    我点击花园提示我收藏花园成功,点击前端提示我收

    藏到前端成功

    感觉有难度,我现在偷懒不搞了,希望有人搞成功分享一下

    补充

    看到这里可能会觉得道哥的代码似乎可以无脑用了,好像确实没毛病

    但是当我们请求响应的内容是text的时候就需要稍微改一下了

    let oldfetch = fetch;
        function fuckfetch() {
            return new Promise((resolve, reject) => {
                oldfetch.apply(this, arguments).then(response => {
                    const oldJson = response.text;
    
                    response.text = function () {
                        return new Promise((resolve, reject) => {
                            oldJson.apply(this, arguments).then(result => {
                                console.log(result)
                                resolve(result);
                            });
                        });
                    };
    
                    resolve(response);
                });
            });
        }

    顺便百度了一下call和apply的区别

    当使用call时,因为它将参数作为单独的参数传递,如果您尝试传递多个参数,它将无法正常工作,例如:
    oldfetch.call(this, url, options).then(response => {
      // code
    });
    
    这段代码试图使用call调用oldfetch函数,并将url和options作为参数。但是,由于call只能一次传递一个参数,因此它将options视为单独的参数,而不是oldfetch函数的第二个参数。
    相反,使用apply可以将参数作为数组传递,例如:
    oldfetch.apply(this, [url, options]).then(response => {
      // code
    });
    
    在这种情况下,oldfetch函数的参数被打包到一个数组中,并使用apply将它们传递给函数。

    完整的Demo

    返回response.text使用这个

    <!DOCTYPE html>
    <html>
    <head>
        <title>Custom Fetch Example</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <h1>Custom Fetch Example</h1>
        <div id="result"></div>
        <script>
        let oldfetch = fetch;
        function fuckfetch() {
        return new Promise((resolve, reject) => {
        oldfetch.apply(this, arguments).then(response => {
        const oldJson = response.text;
    
        response.text = function() {
        return new Promise((resolve, reject) => {
        oldJson.apply(this, arguments).then(result => {
        console.log(result)
        resolve(result);
        });
        });
        };
    
        resolve(response);
        });
        });
        }
        fuckfetch('http://localhost:12600/ziji')
        .then(response => response.text())
        .then(data => {
        console.log(data);
        document.getElementById('result').innerText = JSON.stringify(data);
        })
        .catch(error => console.error(error));
        </script>
    </body>
    </html>

    随便找一个请求地址返回为text替换掉http://localhost:12600/ziji

    返回response.json使用这个

    <!DOCTYPE html>
    <html>
    
    <head>
      <title>Custom Fetch Example</title>
      <meta charset="UTF-8">
    </head>
    
    <body>
      <h1>Custom Fetch Example</h1>
      <div id="result"></div>
      <script>
        // 重新定义 fetch 函数
        let oldfetch = fetch;
        function fuckfetch() { 
            return new Promise((resolve, reject) => { 
                oldfetch.apply(this, arguments).then(response => { 
                    const oldJson = response.json; 
    
                    response.json = function() { 
                        return new Promise((resolve, reject) => { 
                            oldJson.apply(this, arguments).then(result => { 
                                result.hook = 'success'; 
                                resolve(result); 
                            }); 
                        }); 
                    }; 
    
                    resolve(response); 
                }); 
            }); 
        }
    
        // 使用重写后的 fetch 进行请求
        fuckfetch('https://jsonplaceholder.typicode.com/todos/1')
            .then(response => response.json())
            .then(data => {
                console.log(data);
                document.getElementById('result').innerText = JSON.stringify(data);
            })
            .catch(error => console.error(error));
      </script>
    </body>
    
    </html>

    image.png

    已有1人评分好评 油猫币 贡献 理由
    王一之 + 1 + 8 + 1 赞一个!

    查看全部评分 总评分:好评 +1  油猫币 +8  贡献 +1 

    I frequently record, because want to leave something.
  • TA的每日心情
    无聊
    2023-11-2 17:37
  • 签到天数: 275 天

    [LV.8]以坛为家I

    111

    主题

    446

    回帖

    961

    积分

    荣誉开发者

    积分
    961

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

    发表于 2023-4-5 12:56:16 | 显示全部楼层
    I frequently record, because want to leave something.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    5 天前
  • 签到天数: 119 天

    [LV.6]常住居民II

    29

    主题

    598

    回帖

    535

    积分

    专家

    积分
    535

    油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2023-4-5 13:12:32 | 显示全部楼层
    哥哥的文章都是要看的,很有深度。哥哥代码写的好,不用问人都很帅气
    入驻爱发电 让这世界充满爱 https://afdian.net/a/vpannice
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2023-11-2 17:37
  • 签到天数: 275 天

    [LV.8]以坛为家I

    111

    主题

    446

    回帖

    961

    积分

    荣誉开发者

    积分
    961

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

    发表于 2023-4-5 13:34:07 | 显示全部楼层
    脚本体验师001 发表于 2023-4-5 13:12
    哥哥的文章都是要看的,很有深度。哥哥代码写的好,不用问人都很帅气

    我也看哥哥的脚本学习了
    I frequently record, because want to leave something.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-13 10:14
  • 签到天数: 211 天

    [LV.7]常住居民III

    290

    主题

    3880

    回帖

    3797

    积分

    管理员

    积分
    3797

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2023-4-5 14:54:10 | 显示全部楼层
    这样好像没判断来源?什么fetch请求都会提示收藏成功
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。/ 微信公众号:一之哥哥
    回复

    使用道具 举报

  • TA的每日心情
    无聊
    2023-11-2 17:37
  • 签到天数: 275 天

    [LV.8]以坛为家I

    111

    主题

    446

    回帖

    961

    积分

    荣誉开发者

    积分
    961

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

    发表于 2023-4-5 15:49:50 | 显示全部楼层
    王一之 发表于 2023-4-5 14:54
    这样好像没判断来源?什么fetch请求都会提示收藏成功

    是的,这个只是大概写了一下,我暂时主要没有遇到类似的需求,实在是不想专门研究,太难了
    I frequently record, because want to leave something.
    回复

    使用道具 举报

    发表回复

    本版积分规则

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