前端模拟后端接口返回数据的方法

前端功能开发过程中需要用到后端接口的返回数据,若此时后端接口未开发完成或者因其他原因无法使用时,可以使用以下几种方法,根据前后端接口文档定义好模拟数据进行使用。

方法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文件中与请求关联起来,当请求过多时,两者关联过于繁琐

解决方案: 统一模拟数据文件的请求方式,将文件全部放到一个目录中,根据请求路径逐层放置

实现: 见【优化


优化

为了解决缓存问题及统一请求路径,现做如下处理:

  1. 在项目根目录下配置config/api.js,配置信息详见文件内容。
    在其中获取请求路径对应本地文件路径下的文件内容,如果存在对应的文件,则先清除相应的缓存信息并获取文件内容后返回,否则返回错误信息。
  2. 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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值