封装 Fetch 以及增加接口模拟请求
一、软件安装
为了实现接口模拟和请求封装,我们需要安装以下依赖:
-
安装 Mock.js
Mock.js 用于生成模拟数据:
bashnpm install mockjs --save-dev
-
安装 Express
Express 用于搭建模拟后端服务:
bashnpm install express
-
安装 Concurrently
Concurrently 用于同时启动前端项目和 Express 服务:
bashnpm install concurrently --save-dev
二、封装 Fetch
为了简化 Fetch 的使用并处理常见的请求逻辑,我们对 Fetch 进行了 Promise 封装。以下是封装代码:
typescript
class FetchUtil {
/**
* 发送 POST 请求
* @param url 请求的 URL
* @param body 请求体数据
* @param headers 自定义请求头(可选)
* @returns Promise<any> 返回一个 Promise,解析为响应数据
*/
static post<T>(
url: string,
body: T,
headers: Record<string, string> = {}
): Promise<any> {
return new Promise((resolve, reject) => {
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json', // 默认 Content-Type
...headers // 合并自定义请求头
},
body: JSON.stringify(body) // 将 body 转换为 JSON 字符串
})
.then((response) => {
if (!response.ok) {
reject(new Error(`HTTP error! status: ${response.status}`));
}
return response.json();
})
.then((data) => resolve(data)) // 解析响应数据为 JSON
.catch((error) => {
console.error('Error in POST request:', error);
reject(error); // 捕获并传递错误
});
});
}
}
export default FetchUtil;
优化建议 :
在实际项目中,可以进一步优化封装,例如提取 URL 中的 IP 和端口,作为静态配置,以区分开发、测试和生产环境。
三、模拟后端数据
最初尝试使用 Mock.js 模拟接口,但发现请求始终返回 404 错误。经过排查,推测是 React 路由拦截了 /api
请求,导致 Mock.js 无法生效。因此,我们改用 Express 模拟后端服务。
-
Vite 反向代理配置
在
vite.config.ts
中配置反向代理,将/api
请求转发到 Express 服务:typescriptexport default defineConfig({ plugins: [react()], resolve: { alias: { '@': path.resolve(__dirname, './src'), // 定义 @ 为 src 目录 }, }, server: { proxy: { '/api': { target: 'http://localhost:5000', // 后端服务地址 changeOrigin: true, // 修改请求头中的 Origin }, }, }, });
-
修改启动脚本
在
package.json
中添加 Concurrently 脚本,同时启动 Vite 和 Express 服务:json"scripts": { "dev": "concurrently \"vite\" \"node src/mock/mock-server.js\"", "build": "tsc -b && vite build", "lint": "eslint .", "preview": "vite preview" }
-
Express 模拟 API 服务
使用 Express 搭建模拟后端服务:
typescriptimport express from 'express'; import Mock from 'mockjs'; const app = express(); const PORT = 5000; app.use(express.json()); // 模拟登录接口 app.post('/api/login', (req, res) => { const { username, password } = req.body; if (username === 'admin' && password === '123456') { res.json({ success: true, message: '登录成功!', data: { token: 'mock-token' }, }); } else { res.status(401).json({ success: false, message: '用户名或密码错误!', }); } }); // 模拟其他接口 app.get('/api/data', (req, res) => { res.json({ success: true, data: Mock.mock({ 'list|5': ['@id'], }), }); }); // 启动服务 app.listen(PORT, () => { console.log(`Mock server is running on http://localhost:${PORT}`); });
-
集成 FetchUtils
在
login.tsx
中使用封装的 FetchUtils 发送请求:typescriptFetchUtil.post('/api/login', body) .then((data) => { setLoading(false); if (data.success) { message.success('登录成功!'); SessionStorageUtil.setItem('user', { username: values.username }); navigate('/dashboard'); // 登录成功后跳转到 Dashboard } else { message.error('用户名或密码错误!'); } }) .catch((error) => { setLoading(false); message.error('登录失败,请稍后再试!'); console.error('Login error:', error); });
四、总结
在实现接口模拟的过程中,最初尝试使用 Mock.js,但发现请求始终返回 404 错误。经过排查,推测是因为 React 路由拦截了 /api
请求,导致 Mock.js 无法生效。为了解决这一问题,改为使用 Express 搭建模拟后端服务,并通过 Vite 的反向代理配置将请求转发到 Express 服务。最终,成功实现了接口模拟。
为了同时启动前端项目和 Express 服务,我们使用了 Concurrently 工具,并修改了 package.json
中的启动脚本:
json
"dev": "concurrently \"vite\" \"node src/mock/mock-server.js\""
通过这一方案,我们不仅解决了 Mock.js 的问题,还为项目提供了一个灵活的接口模拟方案。虽然对 Mock.js 的问题尚未完全理解,但 Express 的方案已经满足了当前的开发需求。
五、代码资源
项目完整代码托管于 Gitee,地址为:gitee.com/animal-fox_...