前端功能开发过程中需要用到后端接口的返回数据,若此时后端接口未开发完成或者因其他原因无法使用时,可以使用以下几种方法,根据前后端接口文档定义好模拟数据进行使用。
方法1. 直接在接口代码中写死数据
在涉及到的相关接口代码中直接写死返回数据。
- 当后端返回数据内容较多时,比较繁琐,且后续操作中需要删除这些数据,不方便。
- 当返回数据内容比较简单时,可以使用该种方法。
方法2. 将模拟数据存放在json文件或者js脚本中,通过请求的方式获取数据
将模拟数据按照约定好的格式编辑成JSON文件,通过请求的方式获取文件内容,然后再进行相关的处理。
示例:
assets/mock-data/user-center/sysUserLogin.json
文件内容
{
"retCode": "000000",
"retMsg": "成功"
}
通过请求的方式获取文件内容
this.http.get('assets/mock-data/user-center/sysUserLogin.json').subscribe(() => {
}, () => {
});
方法3. 使用server-mock
服务模拟数据
方法4. 使用node搭建简单服务器接收请求返回数据
4.1 安装node和npm包管理器
4.2 安装 Express框架
npm install -g express-generator
4.3 创建express应用
例如创建名称为mock-data的应用
express --view=pug mock-data
4.4 在项目根目录下安装项目所需依赖
npm i
4.5 运行项目
npm start
浏览器访问http://localhost:3000
,可以看到页面上显示如下信息,则说明已经成功启动服务了。
Express
Welcome to Express
浏览器访问http://localhost:3000/users
,可以看到页面上显示如下信息:
respond with a resource
打开routes/users.js
文件,可以看到该页面的返回信息是在此文件中定义的。
在此基础上,根据前端项目的需要在本项目中定义返回模拟数据的js文件,在app.js
文件中引入相应的js文件并将请求的url与js文件关联起来。
// 在app.js中
var jsRouter = require('./routes/js-file'); // 引入js文件
app.use('/users', jsRouter ); // 将请求与返回模拟数据的js文件关联起来
上面的步骤完成后,启动项目,简易的返回模拟数据的服务器已经可以使用了。
但是还存在一些问题:
问题1:改变对应的请求的文件内容时,请求返回的数据未更新
问题原因: 项目启动后,已访问的请求会先读取缓存中的数据,改变的文件内容未更新到缓存。
解决方案: 每次更改请求对应的文件内容后,重启项目,或者修改请求时的js,使每次请求时不获取缓存内容,每次重新获取文件内容
问题2:返回模拟数据的js文件需要在app.js
文件中与请求关联起来,当请求过多时,两者关联过于繁琐
解决方案: 统一模拟数据文件的请求方式,将文件全部放到一个目录中,根据请求路径逐层放置
实现: 见【优化】
优化
为了解决缓存问题及统一请求路径,现做如下处理:
- 在项目根目录下配置
config/api.js
,配置信息详见文件内容。
在其中获取请求路径对应本地文件路径下的文件内容,如果存在对应的文件,则先清除相应的缓存信息并获取文件内容后返回,否则返回错误信息。 - 在
app.js
文件中引用api.js
,修改请求url的配置。
api.js
文件内容如下:
var fs = require('fs');
/**
* 检查请求的路径是否存在
* @param apiName 请求路径
* @param method 请求方式
* @param params 请求参数
* @param response 返回请求
*/
function getDataFromPath(apiName, method, params, response) {
console.log(`请求信息日志:======> start`);
console.log('request URL:' + apiName + `\n`, 'request method:' + method);
console.log(`请求信息日志:======> end`);
if (apiName) {
// 使用fs.access()方法判断文件和目录是否存在
fs.access(
// 提取请求路径中的js文件
apiName.substring(1) + '.js',
// 回调函数,检查请求的路径是否有效失败返回一个错误参数
function (err) {
if (!err) {
// 每次请求都清除模块缓存重新请求
delete require.cache[require.resolve('..' + apiName)];
try {
// 请求文件内容,getData()方法为文件内容中的数据获取方法
addApiResult(response, method, require('..' + apiName).getData(method, params));
} catch (e) {
console.error(e.stack);
response.status(500).send(apiName + ' has an error, please check the code.');
}
} else {
addApiResult(response, method);
}
}
);
} else {
addApiResult(response, method);
}
}
/**
* 设置响应头
* @param response
*/
function setApiHeader(response) {
response.setHeader('Content-Type', 'application/json;charset=utf-8');
response.header("Cache-Control", "no-cache, no-store, must-revalidate");
response.header("Pragma", "no-cache");
response.header("Expires", 0);
response.header('Access-Control-Allow-Origin', '*');
}
/**
* 返回参数,如无返回参数返回404
* @param response 响应信息
* @param method 方法
* @param result 请求结果
*/
function addApiResult(response, method, result) {
if (result) {
response.send(result);
} else {
response.status(404).send();
}
}
/** 请求方式 */
// get
exports.get = function (request, response) {
setApiHeader(response);
getDataFromPath(request.path, 'GET', request.query, response);
};
// post
exports.post = function (request, response) {
setApiHeader(response);
getDataFromPath(request.path, 'POST', request.body, response);
};
app.js
修改内容如下:
// 注释以下几行代码
// app.use('/', indexRouter);
// app.use('/users', usersRouter);
// app.use(function(req, res, next) {
// next(createError(404));
// });
// 1.引入api.js
var api = require('./config/api');
// 2. 配置请求
app.get('/', function (req, res) {
res.send('hello world');
});
app.get('/api/*', api.get);
app.post('/api/*', api.post);
app.options('/api/*', function (req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
res.sendStatus(200); // 让options请求快速返回
});
在app.js
中,如果需要的话还可以在配置请求之前对请求的url做一些处理,比如请求的url不是“/”且不以“/api”开头,则自动在请求url前补上“/api”。
当然还可以做一些其他需要的处理。
app.use(function (request, response, next) {
if (request.url && request.url !== '/' && !request.url.startsWith('api')) { // 如果请求url不是“/”且不是以“/api”开头,则自动补上
request.url = '/api' + request.url;
}
next();
});
更多详细代码请查看github项目代码:
github项目地址:https://github.com/ZHG-XIAO/mock-data.git
参考文档
— END —