manifest.json 中的权限

"permissions": [
    "proxy",
    "unlimitedStorage",
    "",
    "declarativeContent",
    "browsingData",
    "cookies",
    "tabs",
    "storage",
    "notifications",
    "webRequest",
    "webRequestBlocking",
    "http://*/*",
    "http://*/*",
    "debugger",
    "activeTabs"
  ],

一、使用 webRequest

使用权限 "webRequest","webRequestBlocking"
在背景页中拦截并发出请求获取数据,
webRequest只能拦截到请求,想要获取响应数据可以重发一次请求

const axios = require('axios');
//封装get请求
function axiosGet(url){
    return new Promise((res,rej)=>{
        axios.get(url).then(e=>{
            res(e)
        }).catch(e=>{
            rej(e)
        })
    })
}

/**
 * 拦截请求并修改指定请求头信息
 */
chrome.webRequest.onBeforeSendHeaders.addListener(async function (details) {
		// 可以自行添加头部
        details.requestHeaders.push({name: 'Referer', value: 'http://h5.m.taobao.com/'});
        if (details.tabId != -1) {
            if (/getdetail|getdesc/.test(details.url) && !/i=6666/.test(details.url)){
                let res = await axiosGet(`${details.url}&i=6666`)
                console.log('res',res)
            }
        }
        return { requestHeaders: details.requestHeaders };
    }, {
        urls: [
            "*://h5api.m.taobao.com/h5/mtop.taobao.detail.*",
        ]
    }, ['blocking', 'requestHeaders','extraHeaders']
);

二、使用 debugger

使用权限 "debugger","activeTabs"
背景页使用该方法

async function debuggerAttach() {
let currentTab;
let version = '1.3';
let debuggee = ''
chrome.tabs.query({url: '所要监听页面的url'}, (tabs) => {
currentTab = tabs[0]
chrome.debugger.attach({
tabId: currentTab.id
}, version, onAttach.bind(null, currentTab.id));
});
function onAttach(tabId) {
if (chrome.runtime.lastError) {
console.log('onAttach-Error', chrome.runtime.lastError);
return
}
console.log("onAttach-Success");
chrome.debugger.sendCommand({
tabId: tabId
}, "Network.enable");
chrome.debugger.onEvent.addListener(allEventHandler);
}
function allEventHandler(debuggeeId, message, params) {
debuggee = debuggeeId
if (currentTab.id !== debuggeeId.tabId) {
console.log('currentTab.id !== debuggeeId.tabId')
return;
}
if (message === "Network.responseReceived") {
let url = params?.response?.url
chrome.debugger.sendCommand({
tabId: debuggeeId.tabId
}, "Network.getResponseBody", {
"requestId": params.requestId
}, async function (response) {
console.log('response======>', response)
}
});
}
}
console.log('关闭调试')
debuggee && chrome.debugger.detach(debuggee)
}
debuggerAttach()

三、使用 ajax_interceptor_manny

该方法只能拦截到 Fetch/XHR 类型 的数据

window.ajax_interceptor_manny = {
settings: {
switchOn: false,
switchQuery:false
},
originalXHR: window.XMLHttpRequest,
myXHR: function() {
let pageScriptEventDispatched = false;
const modifyResponse = () => {
//this.responseText = overrideTxt;
//this.response = overrideTxt;
if (pageScriptEventDispatched) {
return;
}
pageScriptEventDispatched = true;
ajax_interceptor_manny.download(this.responseText, this.responseURL);
}
// new 一个原生的 XMLHttpRequest 不需要参数,将 xhr 的属性,都复制给this,暴露到外面
const xhr = new ajax_interceptor_manny.originalXHR();
for (let attr in xhr) {
if (attr === 'onreadystatechange') {
xhr.onreadystatechange = (...args) => {
if (this.readyState == 4 && this.status == 200) {
// 请求成功
if (ajax_interceptor_manny.settings.switchOn) {
// 开启拦截
modifyResponse();
}
}
this.onreadystatechange && this.onreadystatechange.apply(this, args);
}
continue;
} else if (attr === 'onload') {
xhr.onload = (...args) => {
// 请求成功
if (ajax_interceptor_manny.settings.switchOn) {
// 开启拦截
modifyResponse();
}
this.onload && this.onload.apply(this, args);
}
continue;
}
if (typeof xhr[attr] === 'function') {
this[attr] = xhr[attr].bind(xhr);
} else {
if (attr === 'responseText' || attr === 'response') {
var k = "_"+attr;
Object.defineProperty(this, attr, {
get: () => this[k] == undefined ? xhr[attr] : this[k],
set: (val) => this[k] = val,
});
} else {
Object.defineProperty(this, attr, {
get: () => xhr[attr],
set: (val) => xhr[attr] = val,
});
}
}
}
},
originalFetch: window.fetch.bind(window),
myFetch: function(...args) {
return ajax_interceptor_manny.originalFetch(...args).then((response) => {
if (response.ok) {
response.clone().text().then((res) => {
ajax_interceptor_manny.download(res, response.url);
}).catch((e) => {
console.warn(e)
});
}
return response;
});
},
download(data, url) {
try {
if (ajax_interceptor_manny.settings.switchOn) {
if (data && typeof data == "string") {
data = JSON.parse(data);
data.url = url;
}
if (data){
//遍历需要捕获的接口
captureInterfaces.forEach((item)=>{
if(data.url.indexOf(item) >-1){
console.log('data',data)
}
}
})
}
}
} catch (e) {
console.error("数据获取失败", e);
}
},
setSetting(data) {
if (typeof data !== "object") {
return;
}
//设置环境
for (var i in data) {
ajax_interceptor_manny.settings[i] = data[i];
}
},
init() {
window.XMLHttpRequest = ajax_interceptor_manny.myXHR;
window.fetch = ajax_interceptor_manny.myFetch;
}
}
ajax_interceptor_manny.init();
ajax_interceptor_manny.setSetting({
switchOn:true
})

四、拦截 script 类型 数据

可以使用js注入拦截方法,如未获取到可使用setTimeout等待

let jsonp1 = ''
let jsonp2 = ''
window.setTimeout(()=>{
window.mtopjsonpCopy1 = window.mtopjsonp1
window.mtopjsonp1 = function(res) {
console.log('@@@@@mtopjsonp1',res)
jsonp1 = res
window.mtopjsonpCopy1(res)
window.setTimeout(()=>{
window.mtopjsonpCopy3 = window.mtopjsonp3
window.mtopjsonp3 = function(res) {
console.log('@@@@@mtopjsonp3',res)
jsonp2 = res
window.mtopjsonpCopy3(res)
}
},200)
}
},200)
本站无任何商业行为
个人在线分享 » Chrome 谷歌插件开发 监听网页请求和响应数据
E-->