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

[油猴脚本开发指南]XHR的返回内容劫持

[复制链接]
  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    633

    主题

    5173

    回帖

    6052

    积分

    管理员

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

    积分
    6052

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

    发表于 2021-8-10 18:42:53 | 显示全部楼层 | 阅读模式

    警告

    文末有修改版代码

    xhr返回内容劫持是我在一个无聊日子搞出来的玩应,并没有一次应用于实践

    可能对一些条件的判断存在问题,另外proxy会在频繁通信中降低性能!

    理论存在更好的解决方法,在此仅提供一个思路作为参考

    开始

    具体代码可以参考https://bbs.tampermonkey.net.cn/thread-769-1-1.html

    var oldxhr=window.XMLHttpRequest
    function newobj(){}

    首先声明一个变量获取xhr

    然后保存,并且创建一个newobj的函数

    window.XMLHttpRequest=函数

    对window下的xhr进行劫持,劫持后创建的xhr都由我们负责创建

    let tagetobk=new newobj();
    tagetobk.oldxhr=new oldxhr();

    对空newobk函数进行一个new创建出一个对象

    并创建一个xhr挂载到对象上,方便使每次创建的xhr跟对象对应

    let handle={
    get: function(target, prop, receiver) {
    if(prop==='oldxhr'){
    return Reflect.get(target,prop);
    }
    if(typeof Reflect.get(target.oldxhr,prop)==='function')
    {
    if(Reflect.get(target.oldxhr,prop+'proxy')===undefined)
    {
    target.oldxhr[prop+'proxy']=new Proxy(Reflect.get(target.oldxhr,prop), {
    apply: function(target, thisArg, argumentsList) {
    debugger;
    return Reflect.apply(target, thisArg.oldxhr, argumentsList);
    }
    });        }
    return Reflect.get(target.oldxhr,prop+'proxy')
    }
    if(prop.indexOf('response')!==-1)
    {
    console.log('我们劫持成功了!',Reflect.get(target.oldxhr,prop))
    return 'FFFFFFFFUCK'
    }
    return Reflect.get(target.oldxhr,prop);
    },
    set(target, prop, value) {
    return Reflect.set(target.oldxhr, prop, value);
    },
    has(target, key) {
    debugger;
    return Reflect.has(target.oldxhr,key);
    }

    对这个空对象进行proxy处理,set的时候自动设置到对象下的oldxhr上

    当获取属性的时候判断是否是oldxhr,如果是就返回oldxhr

    如果不是则判断获取的是否是函数

    并判断获取的属性名+proxy是否存在,如果存在则执行,如果不存在则创建一个

    创建的函数也是一层proxy

    通过proxy的apply函数修改this指针指向其自身的xhr

    然后判断查询数据是否带有response,如果带有则我们获取返回数据并开始劫持

    如果不带有则返回默认的数据

    这样我们就可以在通过对xhr进行劫持的下对数据进行劫持和过滤了!

    更新

    // ==UserScript==
    // @name         XHR劫持返回内容例子
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  try to take over the world!
    // @author       You
    // @match        https://bbs.tampermonkey.net.cn/*
    // @icon         https://www.google.com/s2/favicons?domain=undefined.
    // @grant        none
    // ==/UserScript==
    var oldxhr=window.XMLHttpRequest
    function newobj(){}
    
    window.XMLHttpRequest=function(){
        let tagetobk=new newobj();
        tagetobk.oldxhr=new oldxhr();
        let handle={
            get: function(target, prop, receiver) {
                if(prop==='oldxhr'){
                    return Reflect.get(target,prop);
                }
                if(typeof Reflect.get(target.oldxhr,prop)==='function')
                {
                    if(Reflect.get(target.oldxhr,prop+'proxy')===undefined)
                    {
                        target.oldxhr[prop+'proxy']=(...funcargs)=> {
                            let result=target.oldxhr[prop].call(target.oldxhr,...funcargs)
                            console.log('函数劫持获取结果',result)
                            return result;
                        }
    
                    }
                    return Reflect.get(target.oldxhr,prop+'proxy')
                }
                if(prop.indexOf('response')!==-1)
                {
                    console.log('属性劫持结果',Reflect.get(target.oldxhr,prop))
                    return Reflect.get(target.oldxhr,prop)
                }
                return Reflect.get(target.oldxhr,prop);
            },
            set(target, prop, value) {
                return Reflect.set(target.oldxhr, prop, value);
            },
            has(target, key) {
                debugger;
                return Reflect.has(target.oldxhr,key);
            }
        }
    
        let ret = new Proxy(tagetobk, handle);
    
        return ret;
    }

    这里在cxxjackie的指导下进一步修改了代码

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

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

    2022-8-15 10:58
  • 签到天数: 1 天

    [LV.1]初来乍到

    9

    主题

    80

    回帖

    88

    积分

    初级工程师

    积分
    88

    新人报道油中3周年挑战者 lv1

    发表于 2021-8-10 20:02:27 | 显示全部楼层
    好!



    没看懂
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    633

    主题

    5173

    回帖

    6052

    积分

    管理员

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

    积分
    6052

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

    发表于 2021-8-10 20:59:56 | 显示全部楼层

    可以等视频版,文字更倾向于大纲
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

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

    使用道具 举报

  • TA的每日心情
    开心
    昨天 18:22
  • 签到天数: 703 天

    [LV.9]以坛为家II

    27

    主题

    733

    回帖

    7212

    积分

    荣誉开发者

    精通各种语言的HelloWord!

    积分
    7212

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

    发表于 2021-8-11 08:06:04 | 显示全部楼层
    学会了!
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    633

    主题

    5173

    回帖

    6052

    积分

    管理员

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

    积分
    6052

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

    发表于 2021-8-11 09:08:01 | 显示全部楼层

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

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

    使用道具 举报

  • TA的每日心情
    开心
    13 小时前
  • 签到天数: 169 天

    [LV.7]常住居民III

    11

    主题

    198

    回帖

    239

    积分

    高级工程师

    积分
    239

    油中2周年

    发表于 2021-8-11 15:03:56 | 显示全部楼层
    向gg学习!!!
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    633

    主题

    5173

    回帖

    6052

    积分

    管理员

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

    积分
    6052

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

    发表于 2021-8-28 03:23:31 | 显示全部楼层
    test
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

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

    使用道具 举报

  • TA的每日心情
    开心
    2022-3-7 09:47
  • 签到天数: 1 天

    [LV.1]初来乍到

    22

    主题

    104

    回帖

    170

    积分

    中级工程师

    积分
    170
    发表于 2021-11-29 22:12:08 | 显示全部楼层
    哥哥有没有这个页面的代码
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    633

    主题

    5173

    回帖

    6052

    积分

    管理员

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

    积分
    6052

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

    发表于 2021-11-29 22:28:46 | 显示全部楼层
    rubinTime 发表于 2021-11-29 22:12
    哥哥有没有这个页面的代码

    这个是菜鸟教程扒下来的,记得声明一个1.xml的文件,要起http服务器测试
    <html>
    <head>
    <script type="text/javascript">
    var xmlhttp;
    function loadXMLDoc(url)
    {
    xmlhttp=null;
    if (window.XMLHttpRequest)
      {// code for IE7, Firefox, Opera, etc.
      xmlhttp=new XMLHttpRequest();
      }
    else if (window.ActiveXObject)
      {// code for IE6, IE5
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
      }
    if (xmlhttp!=null)
      {
      xmlhttp.onreadystatechange=state_Change;
      xmlhttp.open("GET",url,true);
      xmlhttp.send(null);
      }
    else
      {state_Change
      alert("Your browser does not support XMLHTTP.");
      }
    }

    function state_Change()
    {
    if (xmlhttp.readyState==4)
      {// 4 = "loaded"
      if (xmlhttp.status==200)
        {// 200 = "OK"
        document.getElementById('A1').innerHTML=xmlhttp.status;
        document.getElementById('A2').innerHTML=xmlhttp.statusText;
        document.getElementById('A3').innerHTML=xmlhttp.responseText;
        }
      else
        {
        alert("Problem retrieving XML data:" + xmlhttp.statusText);
        }
      }
    }
    </script>
    </head>

    <body>
    <h2>Using the HttpRequest Object</h2>

    <p><b>Status:</b>
    <span id="A1"></span>
    </p>

    <p><b>Status text:</b>
    <span id="A2"></span>
    </p>

    <p><b>Response:</b>
    <br /><span id="A3"></span>
    </p>

    <button onclick="loadXMLDoc('/1.xml')">Get XML</button>

    </body>
    </html>
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

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

    使用道具 举报

  • TA的每日心情
    开心
    2022-3-7 09:47
  • 签到天数: 1 天

    [LV.1]初来乍到

    22

    主题

    104

    回帖

    170

    积分

    中级工程师

    积分
    170
    发表于 2021-11-30 13:26:51 | 显示全部楼层
    李恒道 发表于 2021-11-29 22:28
    这个是菜鸟教程扒下来的,记得声明一个1.xml的文件,要起http服务器测试

    谢谢哥哥
    回复

    使用道具 举报

    发表回复

    本版积分规则

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