chrome插件监听ajax请求
我的插件想要监听网页发出的请求, 然后根据请求的状态来做具体的操作。
实现的方法主要有三种方式
- google官方提供的api
chrome.webRequest
这里在插件中监听宿主页面的ajax - 重写宿主页面的
XMLHttpRequest
这里是在宿主页面中监听自己页面的ajax - 使用jquery提供的
ajaxComplete
这里是在宿主页面中监听自己页面的ajax
chrome.webRequest
首先需要manifest.json在中,声明 webRequest
权限
JS
{
"name": "我的应用",
"permissions": [
"webRequest",
"*://*.google.com/"
],
}
background.js
JS
// background.js
chrome.webRequest.onCompleted.addListener(
function (details) {
if (details.statusCode == 200) {
sendMessageTo("fillingPass", details.tabId, (e) => {
console.log('查询已完成');
})
}
},
{ urls: ["*://xxx.xxxx.com/xxxxxx/userStatus*"] } //监听页面请求,你也可以通过*来匹配。
);
这里监听指定 urls 的接口,接口成功响应后,就会继续往下执行。
- 优点: 简单明了
- 缺点: 不能看到接口的返回结果,只能看到接口响应code和接口url
重写宿主页面的 XMLHttpRequest
将以下代码通过document的方式注入到宿主页面
JS
; (function () {
function ajaxEventTrigger(event) {
var ajaxEvent = new CustomEvent(event, { detail: this });
window.dispatchEvent(ajaxEvent);
}
var oldXHR = window.XMLHttpRequest;
function newXHR() {
var realXHR = new oldXHR();
realXHR.addEventListener('abort', function () { ajaxEventTrigger.call(this, 'ajaxAbort'); }, false);
realXHR.addEventListener('error', function () { ajaxEventTrigger.call(this, 'ajaxError'); }, false);
realXHR.addEventListener('load', function () { ajaxEventTrigger.call(this, 'ajaxLoad'); }, false);
realXHR.addEventListener('loadstart', function () { ajaxEventTrigger.call(this, 'ajaxLoadStart'); }, false);
realXHR.addEventListener('progress', function () { ajaxEventTrigger.call(this, 'ajaxProgress'); }, false);
realXHR.addEventListener('timeout', function () { ajaxEventTrigger.call(this, 'ajaxTimeout'); }, false);
realXHR.addEventListener('loadend', function () { ajaxEventTrigger.call(this, 'ajaxLoadEnd'); }, false);
realXHR.addEventListener('readystatechange', function () { ajaxEventTrigger.call(this, 'ajaxReadyStateChange'); }, false);
return realXHR;
}
window.XMLHttpRequest = newXHR;
})();
JS
window.addEventListener('ajaxReadyStateChange', function (e) {
if (e.detail.readyState == 4 && e.detail.responseURL.indexOf("weixin") >= 0 && e.detail.status == 200) {
console.log(e.detail); // XMLHttpRequest Object
}
});
以上写法经过测试可以抓到
- 优点: ajax都能抓到,能拿到接口返回的数据
- 缺点: 实现较为复杂,需要大量判断条件
下面这种写法没写过,有时间的可以试一下
我是另外一种方式
使用jquery提供的 ajaxComplete
此种方法也是通过 content_script脚本把写好的js代码注入到宿主页面中。只是使用了jquery提供的方法
JS
// 监听 ajax 请求
$(document).ajaxComplete(function (e) {
// console.log(e);
console.log(arguments);
console.log(arguments[1]);
var url = arguments[2].url
, details = arguments[1];
// 没有返回数据 直接刷新
if (details.responseText == "") {
location.reload();
}
// 如果接口返回的 code 不是200 绝对没有成功 刷新
if (url.indexOf("balance/assign") >= 0) {
if (details.status == 504 || details.responseJSON.code == 200) {
// 成功, 在rechargeHandler.js中监听这个事件
var myEvent = new CustomEvent("rachangeOk")
window.dispatchEvent(myEvent)
}else{
var time2 = setTimeout(() => {
// debugger
location.reload();
}, 10000);
}
}
});
})
和第二种方法差不多,jquery包装了一层。能拿到接口返回的具体数据,前提是宿主有引用jquery