怎么修改浏览器的全局fetch和XMLHttpRequest构造

2024-04-02  本文已影响0人  ButICare_b72d

需求简述

修改浏览器全局的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;
})();

上一篇下一篇

猜你喜欢

热点阅读