需求简述
修改浏览器全局的fetch和XMLHttpRequest构造函数是为了拦截和记录所有通过这两种方式发起的网络请求。这可以通过原型链扩展或重写构造函数来实现,以下是一个简单的示例:
对fetch的拦截和记录
// 创建一个包裹原生fetch的函数,保留原有功能并添加记录逻辑
const originalFetch = window.fetch;
window.fetch = function(...args) {
// 记录fetch请求参数
const url = args[0];
console.log('Fetch Request:', url);
// 可以在此处添加更多的请求参数记录,如headers、method等
// 继续执行原生fetch操作
const promise = originalFetch.apply(this, args);
// 记录响应
promise.then(response => {
console.log('Fetch Response:', { status: response.status, url });
// 如果需要记录响应体,可以根据实际情况处理
// response.clone().text().then(text => console.log('Response Body:', text));
return response;
});
return promise;
};
对XMLHttpRequest的拦截和记录
(function() {
// 保存原生XMLHttpRequest构造函数
const XHR = window.XMLHttpRequest;
// 创建一个代理构造函数,继承原生XMLHttpRequest的功能
function CustomXMLHttpRequest() {
const xhr = new XHR();
// 添加新的属性以记录请求
xhr._myRequests = [];
// 重写关键方法以添加记录逻辑
['open', 'send'].forEach(method => {
const originalMethod = xhr[method];
xhr[method] = function(...args) {
if (method === 'open') {
this._myRequests.push({
method: args[0],
url: args[1],
async: args[2] !== false // 第三个参数默认为true,即异步请求
});
}
// 调用原生方法
return originalMethod.apply(this, args);
};
});
// 在xhr.onreadystatechange中记录响应
const _onreadystatechange = xhr.onreadystatechange;
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) { // 当状态变为已完成(已收到响应)
console.log('XHR Request:', xhr._myRequests[xhr._myRequests.length - 1]);
console.log('XHR Response:', { status: xhr.status, responseURL: xhr.responseURL });
// 如果需要记录响应体,可以根据实际情况处理
// xhr.responseText 或 xhr.responseBlob 等
}
// 调用原有的onreadystatechange
if (_onreadystatechange) {
_onreadystatechange.apply(this, arguments);
}
};
return xhr;
}
// 替换window.XMLHttpRequest
window.XMLHttpRequest = CustomXMLHttpRequest;
})();
网友评论