Monkey Patching 是前端监控中无侵入式拦截原生 API 的核心手段,适用于 fetch、XMLHttpRequest 等全局稳定方法,通过重定义属性或原型方法实现日志、计时、错误捕获等,兼容性强、启动早、轻量易落地。

函数拦截(Monkey Patching)是前端监控中最常用、最直接的无侵入式手段之一,尤其适用于对原生 API(如 fetch、XMLHttpRequest、console、setTimeout 等)添加日志、计时、错误捕获或请求改写逻辑,而无需修改业务代码本身。
为什么 Monkey Patching 适合监控原生 API
原生 API 多为全局可访问、行为稳定、调用路径明确的对象方法。它们通常不依赖私有状态或闭包上下文,因此可安全地被临时替换,并在新函数中调用原始实现——这正是 Monkey Patching 的核心模式。
- 不依赖框架或构建工具,兼容所有 JS 运行环境(包括 legacy IE11+、现代浏览器、Node.js)
- 执行时机早,可在第三方 SDK 加载前完成劫持,避免被覆盖
- 逻辑轻量,仅需几行代码即可注入监控点,适合快速落地首屏性能、API 错误率等关键指标
如何安全劫持 fetch 实现请求链路监控
fetch 是最典型的监控目标,但因其属性为 writable: false 且 configurable: false,无法用 Proxy 代理 window 对象来拦截,必须通过 Object.defineProperty 显式重定义。
- 先缓存原始函数:
const originalFetch = window.fetch; - 用
Object.defineProperty覆盖window.fetch,确保不会被某些调试工具或框架意外还原 - 新函数中必须使用
originalFetch.apply(this, args)调用,保证this和参数完整传递(即使fetch不依赖this,也应统一写法以防扩展风险) - 响应体(
Response)是单次读取流,若需多次解析(如同时res.json()和res.text()),必须在then中调用response.clone()备份一份用于日志采集,再将原始response返回给业务层
如何拦截 XMLHttpRequest 实现全生命周期追踪
XMLHttpRequest 比 fetch 更复杂,因其涉及多个事件钩子(open、send、onload、onerror 等),需在原型链上拦截关键方法。
- 重写
XMLHttpRequest.prototype.open:记录请求 URL、method、起始时间 - 重写
XMLHttpRequest.prototype.send:注入自定义 header(如 Trace ID),并保存请求体快照(如非 FormData) - 劫持
XMLHttpRequest.prototype.addEventListener或直接覆盖onload/onerror:捕获响应状态、耗时、大小,并上报异常 - 注意兼容性:IE 中需同时处理
onreadystatechange,判断readyState === 4时才触发监控逻辑
通用封装建议:避免污染与便于维护
直接裸写 Monkey Patch 容易造成重复、耦合和难以卸载。推荐按以下方式组织:
- 每个拦截器独立模块,暴露
install()和uninstall()方法,支持动态启停 - 统一使用装饰器风格包装原函数,保留
try/catch、计时、上下文透传等通用逻辑 - 为拦截行为添加开关控制(如
if (!__MONITORING_ENABLED) return),方便灰度或降级 - 监控数据尽量结构化(含 timestamp、url、duration、status、traceId 等字段),便于后续接入可观测平台

















