ModifyAjaxResponse,修改ajax请求返回值,前后端调试之利器 - oppoic
source link: https://www.cnblogs.com/oppoic/p/17505144.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
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>test</title> </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在控制台向页面注入代码试试
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": [ "<all_urls>" ], "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
五、相关阅读
源码:https://github.com/oppoic/ModifyAjaxResponse
Chrome 商店:https://chrome.google.com/webstore/detail/modifyajaxresponse/odpiadnfijfeggnnodoaaphkkjkmpnia
注:访问不了 Chrome 商店的话,下载源码本地加载src目录
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK