在前端开发中 mock 数据但走原来的接口,有几种常见的方案:
1. 使用 Mock Service Worker (MSW) ⭐ 推荐
拦截网络请求,返回 mock 数据,不需要修改业务代码。
css
npm install msw --save-dev
dart
// src/mocks/handlers.js
import { http, HttpResponse } from 'msw'
export const handlers = [
// 拦截具体接口
http.get('/api/user', () => {
return HttpResponse.json({
id: 1,
name: 'John Doe',
email: 'john@example.com'
})
}),
http.post('/api/login', async ({ request }) => {
const body = await request.json()
return HttpResponse.json({
token: 'mock-token-123',
user: body
})
})
]
javascript
// src/mocks/browser.js (浏览器环境)
import { setupWorker } from 'msw/browser'
import { handlers } from './handlers'
export const worker = setupWorker(...handlers)
javascript
// src/main.js
if (process.env.NODE_ENV === 'development') {
const { worker } = await import('./mocks/browser')
worker.start()
}
2. 代理服务器 + Mock 数据
通过 Vite/Webpack 的 proxy 配置,转发到本地 mock 服务器。
arduino
// vite.config.js
export default {
server: {
proxy: {
'/api': {
target: 'http://localhost:3001', // 本地 mock 服务器
changeOrigin: true
}
}
}
}
3. 拦截器方案(axios/fetch)
在请求拦截器中判断是否需要返回 mock 数据。
javascript
// mockData.js
export const mockDatabase = {
'/api/user': { id: 1, name: 'Mock User' },
'/api/products': [{ id: 1, name: 'Product 1' }]
}
// axios-instance.js
import axios from 'axios'
import { mockDatabase } from './mockData'
const instance = axios.create()
// 添加响应拦截器
instance.interceptors.response.use(
response => response,
error => {
// 如果开启 mock 且有对应的 mock 数据
if (process.env.VITE_USE_MOCK === 'true') {
const mockData = mockDatabase[error.config.url]
if (mockData) {
return Promise.resolve({ data: mockData })
}
}
return Promise.reject(error)
}
)
4. 条件编译 + 环境变量
根据环境变量决定是否使用 mock。
javascript
// api/user.js
import mockData from './mock/user.json'
export async function getUser() {
if (import.meta.env.VITE_USE_MOCK) {
return Promise.resolve(mockData)
}
return fetch('/api/user').then(res => res.json())
}
推荐方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| MSW | 不侵入代码、真实模拟网络请求 | 需要额外配置 | 团队开发、E2E 测试 |
| 代理 + Mock 服务器 | 灵活、可共享 | 需要额外服务 | 多人协作 |
| 拦截器 | 简单快速 | 侵入代码 | 快速开发调试 |
| 条件编译 | 完全控制 | 代码冗余 | 简单场景 |
我推荐使用 MSW,它最接近真实网络请求,且不需要修改业务代码,便于后续切换到真实接口。
使用 Whistle 是一个非常好的选择!它是专业的抓包调试工具,可以直接拦截和替换接口响应,无需修改代码。
5. Whistle Mock 接口方案
1. 安装 Whistle
yaml
npm install -g whistle
# 启动 whistle (默认端口 8899)
w2 start
# 或指定端口
w2 start -p 8899
2. 配置代理
启动后访问 http://localhost:8899 打开管理界面。
浏览器代理设置:
- 手动设置代理:
127.0.0.1:8899 - 或使用 SwitchyOmega 等插件快速切换
3. Mock 数据配置方式
方式 1:直接返回 JSON 数据
在 Whistle Rules 中配置:
bash
# 拦截接口返回 mock 数据
example.com/api/user resBody://{user-mock.json}
然后在 Values 中创建 user-mock.json:
css
{
"code": 0,
"data": {
"id": 1,
"name": "Mock User",
"email": "mock@example.com"
}
}
方式 2:使用本地文件
bash
# 返回本地文件内容
example.com/api/products file:///path/to/mock/products.json
方式 3:使用 Values(推荐)
bash
# 使用 Values 中定义的内容
example.com/api/user resBody://{user-data}
example.com/api/list resBody://{product-list}
在 Values 标签页创建对应的 key-value。
方式 4:转发到本地 Mock 服务器
bash
# 转发到本地 Node.js mock 服务
example.com/api http://127.0.0.1:3001
4. 实用配置示例
perl
# ========== Mock API 配置 ==========
# 用户信息接口
example.com/api/user/info resBody://{user-info}
# 列表接口(支持正则匹配)
example.com/api/goods/list* resBody://{goods-list}
# POST 请求也可以 mock
example.com/api/login resBody://{login-success}
# 延迟响应(模拟慢网络)
example.com/api/slow resBody://{slow-data} resDelay://2000
# 返回错误状态
example.com/api/error statusCode://500 resBody://{error-msg}
# 只 mock 开发环境(通过域名区分)
dev.example.com/api/user resBody://{user-mock}
# 生产环境不拦截
prod.example.com/api/user # 不写规则就走真实请求
5. 高级技巧
按环境区分
bash
# 开发环境 mock
dev.example.com/api resBody://{mock-data}
# 测试环境走真实接口
test.example.com/api # 不配置规则
动态 Mock(使用本地服务器)
创建 mock-server.js:
javascript
const express = require('express')
const app = express()
app.get('/api/user', (req, res) => {
res.json({
id: Math.floor(Math.random() * 1000),
name: 'Dynamic Mock User',
timestamp: Date.now()
})
})
app.listen(3001, () => {
console.log('Mock server running on http://localhost:3001')
})
Whistle 配置:
arduino
example.com/api http://127.0.0.1:3001
组合规则
perl
# 同时设置多个规则
example.com/api/user resBody://{user-data} resCors://* resDelay://1000
6. Whistle vs MSW 对比
| 特性 | Whistle | MSW |
|---|---|---|
| 无需修改代码 | ✅ 完全独立 | ✅ 需初始化代码 |
| 跨项目使用 | ✅ 全局生效 | ❌ 每个项目配置 |
| 调试真实请求 | ✅ 可抓包分析 | ❌ 无法抓包 |
| 团队共享配置 | ✅ 导出规则文件 | ✅ 提交代码仓库 |
| 动态修改 | ✅ 实时生效 | ❌ 需刷新页面 |
| 学习成本 | 中等 | 低 |
7. 快速开始步骤
bash
# 1. 安装并启动
npm install -g whistle
w2 start
# 2. 配置代理
# Chrome: 设置 -> 系统 -> 代理 -> 127.0.0.1:8899
# 3. 访问管理界面
# http://localhost:8899
# 4. 在 Rules 标签添加规则
your-domain.com/api/user resBody://{"code":0,"data":{"name":"Test"}}
# 5. 刷新页面查看效果
8. 推荐工作流
markdown
1. 项目启动前先启动 Whistle: w2 start
2. 配置需要 mock 的接口规则
3. 开发时实时修改 mock 数据(无需重启)
4. 联调时关闭对应规则即可走真实接口
5. 团队共享:导出规则文件提交到代码仓库