Skip to content

请求异常监控

实现方案

fetch 重写

基于 window.fetch 重写一层拦截,fetch请求前请求后做一些上报或其他处理

js
const originFetch = window.fetch;
window.fetch = function () {
  const args = [].slice.call(arguments);
  initReportData(); // 初始化一些上报数据

  return originFetch
    .apply(this, args)
    .then((res) => {
      if (res.status > 200) {
        // 业务请求异常上报
        reportBizError(e);
      } else {
        // 请求上报
        reportData();
      }
    })
    .catch((e) => {
      // 请求异常上报
      reportError(e);
      throw e;
    });
};
const originFetch = window.fetch;
window.fetch = function () {
  const args = [].slice.call(arguments);
  initReportData(); // 初始化一些上报数据

  return originFetch
    .apply(this, args)
    .then((res) => {
      if (res.status > 200) {
        // 业务请求异常上报
        reportBizError(e);
      } else {
        // 请求上报
        reportData();
      }
    })
    .catch((e) => {
      // 请求异常上报
      reportError(e);
      throw e;
    });
};

XMLHttpRequest 重写

js
const xml = window.XMLHttpRequest.prototype;
const open = xml.open;
const setRequestHeader = xml.setRequestHeader;
const send = xml.send;

// 重写xml.open
xml.open = function (method, url) {
  // 收集请求方法和地址
  const args = [].slice.call(arguments);
  open.apply(this);
};

// 重写xml.setRequestHeader
xml.setRequestHeader = function (header, value) {
  // 收集请求头字段
  const args: any = [].slice.call(arguments);
  setRequestHeader.apply(this, args);
};

xml.send = function () {
  let onreadystatechange = xml.onreadystatechange || function () {};
  xml.onreadystatechange = function () {
    const readyArgs: any = [].slice.call(arguments);
    onreadystatechange.apply(this, readyArgs);
    if (xml.readyState === 4) {
      try {
        if ((this.status >= 200 && this.status < 300) || this.status === 304) {
          // 请求上报
          report(data);
        } else {
          // 业务请求异常上报
          reportBiz(data);
        }
      } catch (e) {
        // 请求异常上报
        reportError(e);
      }
    }
  };
  const args: any = [].slice.call(arguments);
  send.apply(this, args);
};
const xml = window.XMLHttpRequest.prototype;
const open = xml.open;
const setRequestHeader = xml.setRequestHeader;
const send = xml.send;

// 重写xml.open
xml.open = function (method, url) {
  // 收集请求方法和地址
  const args = [].slice.call(arguments);
  open.apply(this);
};

// 重写xml.setRequestHeader
xml.setRequestHeader = function (header, value) {
  // 收集请求头字段
  const args: any = [].slice.call(arguments);
  setRequestHeader.apply(this, args);
};

xml.send = function () {
  let onreadystatechange = xml.onreadystatechange || function () {};
  xml.onreadystatechange = function () {
    const readyArgs: any = [].slice.call(arguments);
    onreadystatechange.apply(this, readyArgs);
    if (xml.readyState === 4) {
      try {
        if ((this.status >= 200 && this.status < 300) || this.status === 304) {
          // 请求上报
          report(data);
        } else {
          // 业务请求异常上报
          reportBiz(data);
        }
      } catch (e) {
        // 请求异常上报
        reportError(e);
      }
    }
  };
  const args: any = [].slice.call(arguments);
  send.apply(this, args);
};