不能直接用 Proxy 劫持 API 返回结果来注入 Mock 数据,因为 fetch、XMLHttpRequest 是不可写原生方法,且返回值为运行时生成对象,劫持已错过请求时机;真正可行的是在请求发出前拦截并动态替换响应,通过重定义 fetch 和打补丁 XMLHttpRequest.prototype.send 实现入口劫持与响应拦截,并支持异步规则、模拟真实异步行为、规则与数据解耦及规避代理陷阱。

不能直接用 Proxy 劫持 API 返回结果来注入 Mock 数据——因为 fetch、XMLHttpRequest 等全局 API 是不可写、不可配置的原生方法,Proxy 无法代理它们本身;且返回值(如 Promise)是运行时生成的对象,劫持它已错过请求发起时机,无法干预真实网络行为。
真正可行:在请求发出前拦截并动态替换响应
核心思路是“入口劫持 + 响应拦截”,不等请求发出去,就在调用那一刻判断是否启用 Mock,并同步/异步返回模拟数据:
- 对 fetch 重定义:保存原函数,新函数中先匹配 URL 和 method,命中 mock 规则时直接返回
Promise.resolve(mockData),跳过真实网络请求 - 对 XMLHttpRequest.prototype.send 打补丁:在调用前检查
this.url和this.method,若匹配 mock 路径,则手动触发onload并设置responseText/response,再 return 阻止后续发送 - 支持异步规则:比如“仅当用户登录态为 guest 且页面停留超 5 秒时,/api/order 接口才返回空列表”,这类逻辑可写在 mock 判断函数内,实时计算后决定是否拦截
Mock 数据需复现真实异步特征
只返回静态 JSON 会掩盖 loading、错误、竞态等问题。动态注入必须包含行为维度:
- 用
setTimeout模拟网络延迟(如 200–1200ms),确保 UI 的 loading 状态能被观测到 - 根据请求参数或上下文随机返回 408、503 或空数组,验证前端错误兜底逻辑
- 对分页接口(如
/api/list?page=2),解析 query 字符串,按 page/size 动态生成对应条目数的 mock 列表
规则与数据解耦,便于维护和切换
避免把 mock 逻辑硬编码在劫持函数里。推荐结构:
- 定义 mock rules:数组形式,每项含
match(正则或函数)、handler(返回 Promise 的函数)、enabled(开关) - handler 内可调用统一 mock 工厂(如
mockUser({ id: 123 })),该工厂基于 TypeScript 类型自动生成字段,保证结构一致性 - 通过环境变量(
import.meta.env.VITE_MOCK_MODE)或调试开关控制整套规则是否激活,无需修改业务代码
注意规避常见陷阱
这类劫持看似简单,落地易出问题:
- 不要代理
window或globalThis:它们不是标准可代理对象,且 iframe、Web Worker 中行为不一致 - 避免递归劫持:比如在 mock handler 里又调用了 fetch,可能触发二次拦截,造成死循环
- 保持原始返回类型:mock 返回的 Promise 必须 resolve 同样结构的对象(如
{ ok: true, status: 200, json() { ... } }),否则下游代码会报错
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











