请求参数篡改,响应返回值篡改,请求和响应的拦截注入,请求前的二次确认

1,227 阅读3分钟

背景

  1. 查询加参数了,依赖前端写完界面测试?或者维护postman之类的工具,有点难受。
  2. 有些值依赖前一个请求,比如查看列表,然后查看详情,用postman费劲。
  3. 产品或者测试压根不熟悉postman
  4. ...

目标

我们需要一款能再页面发请求时弹出来参数让你修改,让你进行二次确认的操作,返回值也是同样。

需要一款简单易用的请求修改器,融合页面,和页面相辅相成最好,在需要时触发,不用时关闭,

需找方法

  1. 利用浏览器扩展实现?刚开始我确实是这样想的,我尝试利用浏览器的特定API 如:chrome.webRequest.onBeforeRequest.addListener 但走下去发现是一个死胡同,这个API不支持暂停,无法处理异步请求,返回值操作也累等问题叠加起来,让我在这个问题上对它没啥好感。

  2. 最终我选择了利用几个冷门方法,XMLHttpRequest prompt 本质上我们想要暂停,js能暂停主线程的函数只有不常用的几个api,如XMLHttpRequest中设置为同步时,执行send方法会暂停等待返回值, alertconfirmprompt这三个弹框也会暂停,等待用户反馈。

思路

  1. 重写XMLHttpRequest类,或者重写XMLHttpRequest类的open和send方法
  2. 执行open或者send方法时,获取到参数,调用prompt,将请求的参数打印上去,让用户修改。
  3. 拦截 responseText ,调用prompt,将用原始responseText打印上去让用户修改,暂存起来,用户触发responseText的getter时,给它一份假的。

具体实现

/*请求响应修改器1.0*/class HttpRequest extends window.XMLHttpRequest{
    constructor(){
        super(...arguments);
        this._url="";
        this._params="";
        this.onreadystatechange=null;
        let responseText="";
        Object.defineProperty(this,"responseText",{
            get() {
                return responseText
            },
            set(v) {
                responseText=v
            }
        })
    }
    send(){
        const arr=[...arguments];
        if(arr[0]){
            const params = window.prompt(`———————————— 接口地址 ————————————\n${this._url}\n————————————    参数    ————————————\n${_deCode(arr[0]).join("\n")}`,arr[0]);
            if(params!==null){
                arr[0]=params
            }
        }
        return super.send(...arr)
    }
    open(){
        const arr= [...arguments];
        const url=arr[1];
        if(url){
            const [path,params]=url.split(/\?/);
            this._url = path;
            this._params = params;
            if(this._params){
                const params = window.prompt(`———————————— 接口地址 ————————————\n${this._url}\n————————————    参数    ————————————\n${_deCode(this._params).join("\n")}`,this._params);
                if(params!==null){
                    arr[1]=this._url+"?"+params
                }
            }
        }
        let fn = this.onreadystatechange;
        Object.defineProperty(this,"onreadystatechange",{
            set(v) {
                fn=v;
            }
        });
        super.onreadystatechange=()=>{
            if(this.readyState===4&&this.status===200){
                const responseText = super.responseText;
                if(responseText){
                    const res = window.prompt(`———————————— 接口地址 ————————————\n${this._url}\n————————————  返回值  ————————————\n${responseText.slice(0,50)+(responseText.length>50?'...':"")}`,responseText);
                    if(res!==null){
                        this.responseText=res
                    }else {
                        this.responseText=super.responseText
                    }
                }else {
                    this.responseText=super.responseText
                }
            }
            if(fn)fn();
        };
        return super.open(...arr)
    }
}
function _deCode(params){
    return params.split("&").map((a)=>{
        const [key,value]=a.split("=");
        if(!key)return "";
        return decodeURIComponent(key)+"="+decodeURIComponent(value)
    })
}
window.XMLHttpRequest=HttpRequest;

如何使用上述脚本

  1. 如下图所示
  2. 按下F12键,呼出控制台,打印source标签页
  3. 打开snippet标签页
  4. 新增一个代码段
  5. 在右侧空白区域输入上面的代码
  6. 点击执行即可 (后续所有请求即可都拦截了)

上述除了第五步之外,只需要操作一次,后续只需要打开F12,执行即可。

理论上来说,可以支持几乎所有网站的请求,除非他不用 XMLHttpRequest 有些网站执行没反应是因为iframe嵌套的问题,在console控制台切换下iframe即可,还是不行的话就刷新重试下,也可以评论区反馈。 在这里插入图片描述

功能展示

请求修改展示

在这里插入图片描述

返回值修改展示

在这里插入图片描述

总结

功能简单易上手,效果还是不错的,至少我们组的产品和测试,开发反馈说不错。

结束语:如果遇到了问题,欢迎在评论区交流,如果觉得不错,可以点赞和收藏,持续更新。

  1. 博客中标注原创的文章,版权归原作者 苦中作乐才是人生巅峰所有;
  2. 转载或者引用本文内容请注明来源及原作者;