• ModifyAjaxResponse,修改ajax请求返回值,前后端调试之利器


    一、概要

    先看图

     

    京豆多的离谱,你的第一想法肯定是:按F12修改了网页元素

    没那么简单,你看支持刷新的

     

     

    肯定还是假的,通过 Fiddler 或 Wireshark 等抓包工具修改了响应包;或者干脆改了本地host文件,指向了一个自己写的页面......

    这些都太麻烦了,如果能在当前网页上拦截这个请求,并修改返回值,那才是最简单的

    二、尝试

    一个简单的ajax请求

    复制代码
    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>testtitle>
    head>
    <body>
        <div>
            <input type="button" value="get_data" id="xhr_get">
        div>
        <div>
            <p>id -> <span id="id">span>p>
            <p>title -> <span id="title">span>p>
            <p>userId -> <span id="userId">span>p>
            <p>body -> <span id="body">span>p>
        div>
        <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js'>script>
        <script type="text/javascript">
            $('#xhr_get').on('click', function () {
                $.ajax({
                    url: 'https://jsonplaceholder.typicode.com/posts/1',
                    type: 'GET',
                    success: function (data) {
                        $('#id').text(data.id);
                        $('#title').text(data.title);
                        $('#userId').text(data.userId);
                        $('#body').text(data.body);
                    }
                });
            });
        script>
    body>
    html>
    复制代码

    运行起来,点下按钮看看

     

    如何拦截这个ajax请求并修改返回内容呢?

    可以实现一个自定义的构造函数重写默认的XMLHttpRequest构造函数,使其在触发实际事件之前重写响应即可。按F12在控制台向页面注入代码试试(也可以写到 html页面里,效果一样)

    复制代码
    var ajax_open_original = XMLHttpRequest.prototype.open;
    function intercept_ajax(rule) {
        XMLHttpRequest.prototype.open = function () {
            var open_arguments = arguments;
            var url = open_arguments[1];
            var flag = false;
            var xhrTxt = '';
            if (url.indexOf(rule.pattern) > -1) {
                flag = true;
                xhrTxt = rule.response;
            }
            this.addEventListener('readystatechange', function (event) {
                if (flag && this.readyState === 4) {
                    Object.defineProperty(this, 'response', { writable: true });
                    Object.defineProperty(this, 'responseText', { writable: true });
                    this.response = this.responseText = xhrTxt;
                }
            });
            return ajax_open_original.apply(this, open_arguments);
        };
    };
    intercept_ajax({
        pattern: 'https://jsonplaceholder.typicode.com/posts/1',
        response: JSON.stringify({ id: 1, title: '2', userId: 3, body: 'body' })
    });
    复制代码

     

     

    再次点击按钮,页面已经渲染到新的值了

    由此证明,这条路是行的通的,但是不能每次都按F12注入,应该做到自动注入,并把所有拦截规则维护起来

    三、Chrome插件

    浏览器插件最适合做这个了,新建一个Chrome插件,命名:ModifyAjaxResponse

    manifest.json

    复制代码
    {
        "manifest_version": 3,
        "name": "ModifyAjaxResponse",
        "description": "Modify response text of ajax requests",
        "version": "1.4.0",
        "content_scripts": [
            {
                "matches": [
                    ""
                ],
                "js": [
                    "content_scripts.js"
                ],
                "run_at": "document_start"
            }
        ]
    }
    复制代码

     "run_at": "document_start",页面加载之前就注入 content_scripts.js,看看其内容

    const script = document.createElement('script');
    script.setAttribute('type', 'text/javascript');
    script.setAttribute('src', chrome.runtime.getURL('dist/pageInjectScript.js'));
    document.documentElement.appendChild(script);

    向页面动态加载 pageInjectScript.js,用来重写默认的 XMLHttpRequest 构造函数,实现拦截ajax请求。打开博客园测试一下

     

    可见 pageInjectScript.js 已经加载进来了,这个不是博客园服务器返回的,而是通过Chrome插件注入的。既然已经注入页面了,那当前页面所有的ajax请求都可以被重写

    还差一个维护所有拦截规则的页面。使用 Chrome API 自带的存储 chrome.storage.local 保存即可。简单画个页面,看看最终效果

     

    至此,已经可以指哪打哪,随意修改页面展示内容了

      

    四、总结

    这个当然不是改京豆数量自嗨用的,实际用途以及开发初衷是:前后端对接接口,前端利用本插件,可以快速得到不同的返回值

    注:

    1)本插件仅重写XMLHttpRequest构造函数,F12网络面板里看到的还是原始返回值,但代码可以获取修改后的值;

    2)非开发时间请关闭插件,避免向页面注入无用js

    五、相关阅读

    修改Ajax返回内容

    油猴脚本重写fetch和xhr请求

    ajax-interceptor

    requestly

    六、下载

    源码:https://github.com/oppoic/ModifyAjaxResponse

    Chrome 商店:https://chrome.google.com/webstore/detail/modifyajaxresponse/odpiadnfijfeggnnodoaaphkkjkmpnia

    注:访问不了 Chrome 商店的话,下载源码本地加载src目录 

  • 相关阅读:
    1分钟完成在线测试部署便捷收集班级同学文件的web管理系统
    两个json字符串可以直接用equals比较是否相等吗
    【PTHREAD】线程状态
    搜索框的测试
    JavaScript常用事件详解
    预制菜迎来“黄金时代”,谁能领跑下一个万亿市场
    要我说,还是会写总结的项目经理才吃香
    使用IO流完成项目实战水果库存系统
    在实际工作中如何开展性能测试?
    软件工程毕业设计课题(55)微信小程序毕业设计JAVA企业公司小程序系统设计与实现
  • 原文地址:https://www.cnblogs.com/oppoic/p/17505144.html