前端修改代理、通过node mock后端接口

229 阅读2分钟

在前端开发中,有时候会需要mock接口,虽然有的工具提供了云端mock的功能,但是定制化比较低,所以我用node写了一个mock小工具,主要使用了express、mockjs、cors,

"cors": "^2.8.5",
"express": "^4.19.2",
"mockjs": "^1.1.0"

使用两个文件即可完成这个小功能

在这里插入图片描述 首先搭建一个简单的后端服务,这里使用express server.js :

const express = require('express');
const Mock = require('mockjs');
const app = express();
const port = 3000;
const generateMockTemplate = require('./generateJson.js')
var cors = require('cors')
app.use(cors())

app.post('/mty/mtyOll', (req, res) => {
  const userData = Mock.mock(JSON.parse(generateMockTemplate(
    // json放这里----------------------------------------------------------

    {
      "msg": "",
      "code": "",
      "data": [
        {
          "id": "",
          "userId": "",
          "intCls": 0,
          "intClsName": "",
          "applicant": "",
          "applicantType": 0,
          "applicantAddress": "",
          "brandApplicantNum": 0,
          "brandRegNum": 0,
        }
      ]
    }

    // json放这上边----------------------------------------------------------
  )));
  res.json(userData);
});

// 或者,如果你想要根据请求参数动态生成数据
app.get('/api/example', (req, res) => {
  const userId = parseInt(req.params.id, 10);
  // 假设我们只返回一个用户,根据ID随机匹配或生成
  const user = Mock.mock({
    'id': userId,
    'name': '@cname',
    'age|18-60': 1,
    'city': '@city(true)',
    'email': '@EMAIL'
  });
  res.json(user);
});

// 启动服务器
app.listen(port, () => {
  console.log(`Mock server running at http://localhost:${port}/`);
});

接下来,使用需要接入Mock,mock规则通过Mock.mock来控制,Mock.mock用来记录数据模板。当拦截到匹配 rurl 的 Ajax 请求时,将根据数据模板 template 生成模拟数据,并作为响应数据返回。

mockjs文档参考

接下来就是在generateJson.js中配置自己个性化的数据返回了,具体规则可以参考mockjs文档

generateJson.js:

const Mock = require('mockjs');


function generateMockTemplate(json) {
  let first = true

  function processValue(value, itemKey) {
    // 特性适配
    if (itemKey === 'code') {
      if (first) {
        first = false;
        return '"00000"'; //第一个字段固定值
      } else {
        return '"@integer(0, 8)"';
      }
    } else if (
      itemKey.indexOf('num') > -1 ||
      itemKey.indexOf('Num') > -1 ||
      itemKey.indexOf('int') > -1 ||
      itemKey.indexOf('Int') > -1) {
      return '"@integer(0, 10)"';
    } else if (
      itemKey === 'current' ||
      itemKey === 'total' ||
      itemKey === 'maxTotal' ||
      itemKey === 'size' ||
      itemKey === 'pages') {
      return '"@integer(60, 1000)"'
    } else if (
      itemKey.indexOf('Color') > -1 ||
      itemKey.indexOf('color') > -1) {
      return `"@color"`
    } else if (itemKey.indexOf('Name') > -1) {
      return `"@cword(5,10)"`
    } else if (
      itemKey.indexOf('Price') > -1 ||
      itemKey.indexOf('price') > -1) {
      return `"@natural(2000, 100000)"`
    } else if (itemKey.indexOf('word') > -1) {
      return '"@cword(5,20)"';
    } else if (
      itemKey.indexOf('Status') > -1 ||
      itemKey.indexOf('status') > -1 ||
      itemKey.indexOf('key') > -1 ||
      itemKey.indexOf('Key') > -1||
      itemKey.indexOf('type') > -1 ||
      itemKey.indexOf('Type') > -1) {
      return `"@integer(0, ${value?value:4})"` //可以在模板json中设置最大值
    } else if (
      itemKey.indexOf('Time') > -1 ||
      itemKey.indexOf('Date') > -1) {
      return `"@datetime()"`
    } else if (
      itemKey.indexOf('id') > -1 ||
      itemKey.indexOf('Id') > -1 ||
      itemKey.indexOf('code') > -1 ||
      itemKey.indexOf('Code') > -1||
      itemKey.indexOf('No') > -1 ||
      itemKey.indexOf('no') > -1) {
      return `"@guid"`
    } else if (
      itemKey.indexOf('url') > -1 ||
      itemKey.indexOf('Url') > -1 ||
      itemKey.indexOf('image') > -1 ||
      itemKey.indexOf('Image') > -1 ||
      itemKey.indexOf('File') > -1 ||
      itemKey.indexOf('file') > -1) {
      return '"@url()"';
    } else if (itemKey.indexOf('En') > -1) {
      return '"@title(3, 5)"';
    } else if (
      itemKey.indexOf('Phone') > -1 ||
      itemKey.indexOf('phone') > -1) {
      return Array.from({
        length: 11
      }, () => Mock.Random.pick(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])).join('');
    }

    if (typeof value === 'string') {
      return '"@cword(5,20)"';
    } else if (typeof value === 'number') {
      // 假设数字可能是一个范围
      return `"@integer(0, 10)"`;
      // return `"@integer(${Math.floor(value * 0.8)}, ${Math.ceil(value * 12)})"`; // 生成接近原数字但有一定范围的随机整数
    } else if (typeof value === 'boolean') {
      // 布尔值直接返回
      return `${value}`;
    } else if (Array.isArray(value)) {
      // 数组需要递归处理每个元素,并确定数组长度
      if (value.length === 0) {
        return '[]'; // 空数组直接返回
      }
      const elementTemplate = processValue(value[0], ''); // 假设所有元素类型相同,只取第一个元素作为模板
      return `|${value.length}-${value.length+10}":[${elementTemplate}]`; // 数组长度固定,元素类型相同
    } else if (typeof value === 'object' && value !== null) {
      // 对象需要递归处理每个属性
      let properties = Object.keys(value).map(key => {
        const processedValue = processValue(value[key], key);
        return `"${key}":${processedValue}`;
      }).join(',');
      return `{${properties}}`;
    } else {
      // 其他类型(如null、undefined、function等)可能需要根据实际情况处理
      // 这里简单处理为null
      return 'null';
    }
  }

  const template = processValue(json, '').split('":|').join('|');
  return template;
}

module.exports = generateMockTemplate;

这样,后端服务就ok了,node启动server.js即可运行,我这里使用的是3000端口

接下来,在前端服务配置下代理即可使用:

  1. vue.config.js 中添加如下配置:
        "^/mock/": {
          target: "http://localhost:3000",
          changeOrigin: true,
          pathRewrite: {
            "^/mock/": ""
          }
        }
  1. 在api接口中添加配置如下(基于本项目内容):
        let mock = '/mock';


        export const getCouponInfoById = (params) => {
          return request.post(mock + '/mty/mtyOll', params)
        }
  1. 注意api配置文件中/mty/mtyOll内容与后端服务中server.js填的接口名要相同,代理中的端口号要相同 在这里插入图片描述