96SEO 2026-05-06 20:06 3
在前端开发的日常工作中,我们是不是经常遇到这样的尴尬时刻:界面画得漂漂亮亮,逻辑写得严丝合缝,就卡在等后端接口联调这一步?盯着屏幕上那个转圈的Loading,心里五味杂陈。或者,好不容易拿到了接口文档,结果对方说“字段还没定死”,这种时候,Mock数据就成了我们的救命稻草。

但说实话,传统的Mock方案——比如单纯依赖Mock.js——真的够用吗?生成的全是“张三”、“李四”,或者一堆毫无业务含义的随机数字。这种数据放到页面上,不仅kan不出真实效果,甚至还可Neng掩盖掉潜在的边界Bug。我们需要的是geng智Neng、geng懂业务、甚至Neng“猜”出我们想要什么数据的工具。
今天我想和大家聊聊一套结合了AINeng力的Mock解决方案。这不仅仅是一个工具,geng像是一个Neng理解你业务逻辑的“虚拟后端”。它通过拦截请求、智Neng匹配规则、利用大模型生成高质量数据,以及团队共享机制,彻底解决了联调阻塞、场景覆盖难、数据质量差和数据难共享这四大顽疾。
整体架构:不仅仅是拦截在深入代码细节之前,我们先来kankan这套系统的宏观设计。它不是简单的本地拦截,而是一个分层协作的生态系统。想象一下你的业务代码、本地Mock SDK、可视化面板以及后端AI服务,它们之间是如何优雅地共舞的。
┌─────────────────────────────────────────────────────────────┐
│ 业务项目 │
│ import { mockInit } from '@zz-common/ai_mock' │
│ mockInit │
└────────────────────────────┬────────────────────────────────┘
│
┌────────────────────────────▼────────────────────────────────┐
│ ai_mock │
│ XHR/Fetch 拦截 → 规则匹配引擎 → 返回 Mock 数据 │
└────────────────────────────┬────────────────────────────────┘
│ 动态加载 sdk + CustomEvent 通信
┌────────────────────────────▼────────────────────────────────┐
│ mock-sdk │
│ 请求列表 | 规则管理 | Monaco Editor 编辑器 │
└────────────────────────────┬────────────────────────────────┘
│ HTTP
┌────────────────────────────▼────────────────────────────────┐
│ node │
│ 接口文档获取 → AI 生成 → 数据持久化 │
└─────────────────────────────────────────────────────────────┘
这个架构图展示了数据流动的全过程。业务层无感知,只需引入SDK;中间层负责拦截和分发;面板层提供可视化的控制台;而后端服务则充当“大脑”,利用AI生成高质量的数据。
核心技术:如何优雅地“欺骗”浏览器要实现无侵入的Mock,Zui关键的一步就是拦截网络请求。现代前端应用通常混合使用 XMLHttpRequest 和 fetch API。我们需要同时搞定这两者,而且不Neng破坏原有的业务逻辑。
这里有个棘手的问题:Ru果我们拦截了请求并返回Mock数据,那真实的请求还要不要发?有时候我们需要对比真实数据,有时候又不需要。而且,Ru果不小心处理,hen容易陷入无限递归的泥潭——拦截器发请求,又被拦截器拦截……
1. 拦截 XHR 请求我们通过重写 XMLHttpRequest.prototype.send 来实现拦截。为了防止递归,我们引入了一个 WeakMap 来标记那些“真实”的请求。
// 保存原始方法
const xhrSendNative = XMLHttpRequest.prototype.send
const originalFetch = window.fetch
// 防递归:标记真实请求
const isRealRequest = new WeakMap
XMLHttpRequest.prototype.send = function {
const xhr = this
const url = sliceUrlPath
// 检查是否为标记的真实请求,防止无限递归
if ) {
return xhrSendNative.apply
}
// 检查是否命中 Mock 规则
if {
const mockResult = getMockData
if {
// 1. 立即返回 Mock 响应给业务层
applyMockResponseToXhr
// 2. 后台发送真实请求
const realXhr = cloneXHR // 不复制事件监听器
isRealRequest.set // 标记,防止递归
xhrSendNative.apply
return
}
}
// 未命中:执行原生请求
xhrSendNative.apply
}
这段代码的逻辑非常清晰:先kan是不是“免检”的真实请求,Ru果是放行;Ru果不是检查有没有匹配的Mock规则。Ru果匹配到了就先把Mock数据“喂”给业务代码,让页面立刻动起来。然后在后台悄悄发一个真实请求,把数据存下来方便我们后续对比和调试。
2. 覆写只读属性XHR 对象的hen多属性,比如 readyStatestatusresponse,在浏览器标准中是只读的。直接赋值会报错或者无效。这时候,我们就得用点“黑科技”——Object.defineProperties。
const applyMockResponseToXhr = (
xhr: XMLHttpRequest,
responseData: any,
statusCode: number
) => {
const responseText = typeof responseData === 'string'
? responseData
: JSON.stringify
// 通过 defineProperties 覆写只读属性
Object.defineProperties(xhr, {
readyState: { get: => 4, configurable: true },
status: { get: => statusCode, configurable: true },
response: { get: => responseData, configurable: true },
responseText: { get: => responseText, configurable: true }
})
// 触发标准事件序列
xhr.dispatchEvent)
xhr.dispatchEvent)
xhr.dispatchEvent)
}
通过这种方式,我们实际上是在浏览器面前演了一出“双簧”:XHR对象kan起来像是Yi经完成了请求,状态码是200,数据也有了但实际上这些数据dou是我们塞进去的。
智Neng规则匹配:不仅仅是URL匹配实际业务中,同一个接口往往需要根据不同的参数返回不同的数据。比如 /api/user/info,传 id=1 返回张三,传 id=2 返回李四。Ru果只靠URL匹配,根本玩不转。
我们需要一套geng强大的规则引擎。参数可Neng在 URL Query、Request Body、Header、Cookie 甚至 Path 中。为此,我们设计了 MockRule 接口,支持多维度条件匹配。
interface MockRule {
id: string;
url: string;
name: string;
priority: number; // 优先级,数字越小越优先
enabled: boolean;
type: 0 | 1 | 2; // 0=本地草稿,1=个人云端,2=团队共享
paramConditions: ParamCondition; // 参数条件
mockData: any;
httpStatusCode: number;
delay?: number;
}
interface ParamCondition {
location: 'query' | 'body' | 'header' | 'cookie' | 'path';
paramName: string;
operator: 'equals' | 'notEquals' | 'contains' | 'notContains' |
'greaterThan' | 'lessThan' | 'greaterOrEqual' | 'lessOrEqual';
value: any;
}
匹配算法逻辑
匹配过程遵循“优先级”和“且”逻辑。我们先筛选出所有启用的规则,按优先级排序,然后逐个检查。只有当规则中的所有条件dou满足时才算命中。
function matchRule: MatchResult {
// 只匹配Yi启用的期望,按优先级排序
const enabledRules = rules
.filter
.sort => a.priority - b.priority);
const matched = enabledRules.find);
return matched
? { matched: true, rule: matched, delay: matched.delay ?? 0 }
: { matched: false };
}
function isRuleMatched: boolean {
// 没有参数条件,匹配所有请求
if return true;
// 所有条件dou满足才匹配
return rule.paramConditions.every(condition =>
matchParamCondition
);
}
在获取参数值时我们根据 location 字段从不同的地方“挖”数据。比如从 Body 里取值时我们还要支持嵌套路径,这就需要写一个简单的路径解析函数。
function getParamValue: any {
switch {
case 'query':
return request.query?.;
case 'body':
// 支持嵌套路径,如 body.user.id
return getNestedValue, paramName);
case 'header':
return request.headers?.;
case 'cookie':
return parseCookie;
case 'path':
return extractPathParam;
default:
return undefined;
}
}
这里有个小细节:在Zuo比较的时候,我们会Zuo一些类型兼容处理。比如数字 123 和字符串 "123",在某些场景下应该视为相等,避免因为类型不一致导致匹配失败,毕竟HTTP请求传参时类型转换是hen常见的。
解决了“怎么拦截”和“怎么匹配”,接下来就是Zui核心的问题:“数据从哪来?”
以前我们用 Mock.js,生成的是 @cname@integer。这种数据毫无业务语义。比如订单状态,Mock.js 可Neng给你生成个 5,但实际业务里只有 0、1、2。这种数据放到前端,根本测不出东西。
我们希望根据接口文档中的字段描述、枚举说明、字段命名来生成符合业务语义的数据。文档备注越详细,字段名定义越清晰,生成的数据就越准确。
Prompt 工程的艺术后端服务会从 API 文档平台获取接口的 JSON Schema,然后构建一个精心设计的 Prompt 发给 AI。这个 Prompt 是整个系统的灵魂。
const systemPrompt = `
你是 Mock 数据生成专家,根据 JSON Schema 生成符合业务场景的数据。
1. 若 description 中存在枚举说明,优先使用枚举值本身
2. 若无 description,则根据字段名的语义生成合理值
3. 数组类型默认生成 3 条数据
4. 若 description 中枚举值较多,数组应覆盖所有枚举值
- respCode / code:成功场景为 0,失败场景为 500
- errorMsg:成功场景为 null,失败场景为 "系统异常"
- 图片 URL:使用统一的占位图地址
- 普通 URL:使用统一的域名地址
仅输出 JSON,不附加任何解释文字
`;
你kan,我们不仅告诉 AI 怎么生成,还规定了默认值策略。比如 code 字段,成功时必须是 0,这符合大多数公司的后端规范。
AI 虽然强大,但有时候也挺“调皮”。它可Neng会在 JSON 前面加一句“好的,这是生成的数据”,或者生成的 JSON 格式有细微错误。为了确保万无一失,我们在拿到 AI 的返回结果后会用 jsonrepair 这样的工具进行清洗和修复。
const jsonMatch = result.match;
if {
return jsonrepair;
}
生成后我们还会对比 Schema 和实际数据,Ru果发现字段缺失,会立即发送告警,提醒开发同学检查 Prompt 或者文档定义。
动态模板:响应随请求而变有时候,我们希望 Mock 数据Neng“动”起来。比如请求参数里带了 userId=123,返回的数据里 userId 也得是 123。这就需要用到动态模板语法。
我们支持在 Mock 数据中引用请求参数,实现“响应随请求变化”:
{
"code": 0,
"data": {
"requestId": "{{uuid}}",
"timestamp": "{{Date.now}}",
"userId": "{{request.body.userId}}",
"page": "{{request.query.page}}"
}
}
在渲染数据时我们会解析这些占位符。像 {{request.body.userId}} 会被替换成真实请求 Body 中的 userId,而 {{uuid}} 则会调用我们预定义的函数生成一个唯一标识。这种灵活性让 Mock 场景geng加逼真。
说了这么多技术细节,平时我们到底怎么用呢?下面演示从请求采集到 AI 生成 Mock 数据的完整流程。
安装并初始化 SDK:
// 1. 安装
npm install @zz-common/ai_mock
// 2. 初始化
import { mockInit } from '@zz-common/ai_mock'
mockInit({
rules: , // 拦截的域名
excludeRules: // 排除的资源
})
当你在页面上操作时所有的请求dou会被可视化面板捕获。你Ke以kan到请求列表,选中某一个请求,点击“AI 生成”。系统会自动提取该请求的 Schema,发送给后端,几秒钟后一份高质量的 Mock 数据就躺在编辑器里了。
Ru果 AI 生成的数据还不够完美,你Ke以直接在 Monaco Editor 里微调。面板还提供了“加载真实数据”的按钮,Ke以一键将真实响应填入编辑器,方便基于真实数据修改。
数据清理与持久化随着时间推移,本地会积累大量无用的 Mock 数据,导致存储膨胀。我们内置了一个自动清理机制。
await cleanupInactiveData;
这个函数会自动清理那些超过 30 天未使用的本地数据,或者清理非活跃的数据。对于重要的规则,我们支持三种作用域:本地草稿、个人云端和团队共享。通过 type 字段区分,确保数据既Neng灵活流转,又Neng安全隔离。
目前这套工具Yi在公司内部广泛使用,效果非常明显。前端同学不再需要苦哈哈地等后端接口,测试同学也Neng利用它构造各种复杂的边界场景。AI 的加入,让 Mock 数据从“随机数”变成了“业务数据”,极大地提升了研发效率和场景覆盖率。
当然技术方案没有银弹。这套系统在引入 AI 后也带来了一些新的挑战,比如生成速度、Token 消耗成本等。但总体而言,相比于它带来的效率提升,这些投入dou是值得的。希望这套思路Neng给同样被 Mock 数据困扰的你,带来一些启发。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback