首先
本插件目的是获取指定Ajax请求返回的内容,及该请求的url地址。
Manifest V3
本文使用 Chrome 插件使用V3版本,V3较V2在一些配置项上稍有变动。
2024 年 6 月开始在 Chrome 127 及更高版本中禁用预稳定版 Chrome (Dev、Canary 和 Beta)中的 Manifest V2 扩展。
原理
通过重写 XHR 和 Fetch 请求,拦截所需要的内容,把内容发送到指定url地址。
如下图,xhr、fetch请求已由自定义的 xhr_script.js 文件接管。
如下图,拦截的内容发送至本地的 test.php 文件。
代码
这里贴上插件中的部分代码:
(function(xhr) { var XHR = xhr.prototype; var open = XHR.open; var send = XHR.send; // 对open进行patch 获取url和method XHR.open = function(method, url) { this._method = method; this._url = url; return open.apply(this, arguments); }; // 同send进行patch 获取responseData. XHR.send = function(postData) { this.addEventListener('load', function() { var myUrl = this._url ? this._url.toLowerCase() : this._url; if(myUrl ) { if ( this.responseType != 'blob' && (this.responseType).indexOf('video')<0 && this.responseText) { // responseText is string or null try { var arr = this.responseText; //console.log('请求:', this._url ); // 因为inject_script不能直接向background传递消息, 所以先传递消息到content_script window.postMessage({'url': this._url, "response": arr}, '*'); } catch(err) { console.log(err); console.log("Error in responseType try catch"); } } } }); return send.apply(this, arguments); }; })(XMLHttpRequest); (function () { console.log('====fetch====' ); //重写fetch const fetch_tools = { originalFetch: window.fetch.bind(window), myFetch: function (...args) { console.log('fetch==', args); const getOriginalResponse = async (stream) => { let text = ''; const decoder = new TextDecoder('utf-8'); const reader = stream.getReader(); const processData = (result) => { if (result.done) { return text; } const value = result.value; text += decoder.decode(value, {stream: true}); return reader.read().then(processData); }; return await reader.read().then(processData); } //const [requestUrl, data] = args; //console.log('==requestUrl==', requestUrl); //console.log('==data==', data); let url = args[0]; //测试 if (url.includes('data.bilibili.com/v2/log/web') ) { console.log('###拒绝###'); return Promise.reject('error'); } return fetch_tools.originalFetch(...args).then(async (response) => { //window.postMessage({'url': this._url, "response": arr}, '*'); const originalResponse = await getOriginalResponse(response.body); console.log('==originalResponse==', response ); window.postMessage({'url': response.url, "response": originalResponse }, '*'); if (originalResponse) { const stream = new ReadableStream({ start(controller) { controller.enqueue(new TextEncoder().encode(originalResponse)); controller.close(); } }); const newResponse = new Response(stream, { headers: response.headers, status: matchedInterface && matchedInterface.replacementStatusCode || response.status, statusText: response.statusText, }); const responseProxy = new Proxy(newResponse, { get: function (target, name) { switch (name) { case 'body': case 'bodyUsed': case 'ok': case 'redirected': case 'type': case 'url': return response[name]; } return target[name]; } }); for (let key in responseProxy) { if (typeof responseProxy[key] === 'function') { responseProxy[key] = responseProxy[key].bind(newResponse); } } return responseProxy; } return response; }); }, } window.fetch = fetch_tools.myFetch; })();
更多
插件完整代码下载地址:https://wwz.lanzout.com/iYohv1p9065c
一些参考链接及源代码地址:
Chrome 扩展V3 中文文档:https://doc.yilijishu.info/chrome/
Manifest V2 支持时间表:https://developer.chrome.com/docs/extensions/develop/migrate/mv2-deprecation-timeline
两万+字数:从0到1带你开发 Chrome 浏览器 Manifest V3 版本插件:https://blog.csdn.net/guoqiankunmiss/article/details/135652524
Chrome 浏览器插件从 Manifest V2 升级到 V3 版本所需要修改的点:https://guoqiankun.blog.csdn.net/article/details/135552664
记录Chrome插件从V2版本升级到V3版本的过程中遇到的问题:https://blog.csdn.net/lxm1353723767/article/details/127706101
XHR:https://github.com/zx69/request-retransmission-chrome-extension/blob/master/myXHRScript.js
Fetch:https://github.com/PengChen96/ajax-tools/blob/master/pageScripts/index.js
使用 Chrome 插件拦截广告的原理:https://www.cnblogs.com/yangzhou33/p/13835409.html
还木有评论哦,快来抢沙发吧~