Mock 生成 随机数据、拦截 Ajax 请求。

Mock

在实际项目开发中,后端接口、接口文档可能晚于前端才会开发完成,前端只能等到后端的接口出来以后才能进行开发,这样一来对于前端就显得十分被动,如果有什么东西可以制造一些假的数据用于暂时的测试,模拟后台接口的话,对于前端的开发就方便许多了。而 Mock.js 就正好满足了这样的需求。它的特点就是生成 随机数据、拦截 Ajax 请求。

1. 安装

  1. bootCND bootCND 搜索 “mock” 拷贝地址
  2. mock 官网: mock 官网 下载 mock.js

留着偷懒直接复制粘贴:

<script src="https://cdn.bootcdn.net/ajax/libs/Mock.js/1.0.1-beta3/mock-min.js"></script>

2. 生成随机数据:

语法:

Mock.mock(template);	// template 一个配置对象,数据模版,可以是对象或字符串,根据数据模板来生成数据

参数 template 中的每个属性由 3 部分构成:属性名 name、生成规则 rule、属性值 value,属性名和生成规则间用 | 分隔,生成规则是可选的

"name|rule": value

语法:

Mock.mock({ key: value});

以下代码表示随机生成一个包含3个对象的数组,key 是 list ,value 是一个 array,array 中的每一个 item 又都是一个对象

let data = Mock.mock({
  "list|3": [{
    'id|+1': 1	// 对象的 id 属性从 1 开始自增
  }]
});
console.log(data);
// 如果需要 JSON 格式 则转换为 JSON.stringify(data);

输出:(忽略截图里 key 是 testList 而示例代码 key 是 list。任性,花时间解释,但就是不改!)

mock 常用值:

let data = Mock.mock({
  // key 为 studentsArr, value 为一个数组。数组中随机生成 10 个对象
	"studentsArr|10": [{
    
    // id 属性依次 +1
    "id|+1": 1,
    
    // 随机产生一个中文名 英文名为@name()
    "name": "@cname()",
    
    // 在 16 - 22 间随机产生一个数作为年龄
    "age|16-22": 1,
    
    // 在数组中随机生成一个值作为性别
    "gender|1": ["male", "female"],
    
    // 随机产生一个数字作为成绩
    "score|40-100":1,
    
    // 随机产生一个生日
    "birthday": "@date()",
    
    // 随机生成一个 email 地址
    "email":"@email()",
    
    // 随机生成一个地址,参数可添 true
    "address": "@county()",
    
    // 随机生成一个手机号码,支持正则
    "phoneNumber": /^1[3458]\d{9}$/
  }]
});

3. 拦截 Ajax 请求

Mock 作为客户端向服务器端请求路途中的拦路虎,会拦截 Ajax 请求,当拦截到匹配 rurl 的 Ajax 请求时,将根据数据模板 template 生成模拟数据并作为响应数据返回。

// rurl 表示要拦截的 url
Mock.mock(rurl, template);

一个超简单的 demo:

<input type="button" value="获取数据">

<script src="https://cdn.bootcdn.net/ajax/libs/Mock.js/1.0.1-beta3/mock-min.js"></script>
<script>
  const btn = document.querySelector('[type="button"]'); // 获取 button

  Mock.mock('./getData', function () {
    return Mock.mock({
      'name': '@cname'
    });
  });

  btn.onclick = function () {
    let xhr = new XMLHttpRequest();
    xhr.open('GET', './getData');
    xhr.send();
    xhr.onreadystatechange = function () {
      if (xhr.readyState == 4 && xhr.status == 200) {
        let data = xhr.responseText;
        console.log(data);
      }
    }
  }

按钮点击后,会发送 Ajax 请求,请求 ./getData 文件,但在请求过程中会被 Mock 给拦截,并返回出一个随机数据(第8、9行)一个拥有 “name” 的对象作为 xhr.responseText 的值。

Mock.mock(/getStudents/, function () { // rurl 可以使用正则也可以直接使用 Ajax open 的 url 地址
  return Mock.mock({
    "list|5": [{
      "id|+1": 1,
      'name': "@cname",
      "age|18-25": 1,
      "address": "@county(true)",
      "hobby|1": ["吃饭", "睡觉", "干仗"],
      "tel": /^1[3458]\d{9}$/
    }],
  });
});

btn.addEventListener("click", function () {
  let xhr = window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject("Microsoft.XMLHTTP");
  xhr.open("GET", "/getStudents");
  xhr.send(null);
  xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
      let result = JSON.parse(xhr.responseText);
      console.log(result);
    }
  }
});

4. Mock 搭配 Ajax 模拟登录

假设存在一个表单:

<form action="#" method="get">
  <div>
    账号
    <input type="text" id='username' name='username'>
  </div>
  <div>
    密码
    <input type="text" id='password' name='password'>
  </div>
  <input type="button" value="提交">
</form>

输入内容点击提交后,会在地址栏发现:test.html?username=123&password=123# 即 “=” 左侧是 input 框 name 属性,右侧是实际输入的值,被拼接在 .html 路径后

以下所有代码文件名都有出现不对应的现象。故意的。钓鱼执法,懂?

现在可以携带这些信息,发送 Ajax 请求,再被 Mock 拦截模拟服务器处理,再返回结果:

// 点击按钮发送 Ajax 请求
btn.onclick = function () {
  let xhr = new XMLHttpRequest();
  xhr.open('GET', `./test.html?username=${txt.value}&password=${pwd.value}`);
  xhr.send();
  xhr.onreadystatechange = function () {
    if (xhr.readyState == 4 && xhr.status == 200) {
      let data = xhr.responseText;
    }
  }
}

Mock 部分:

/*
  mock() 参数:
  第 1 个参数格式还可以写 RegExp,表示拦截含有 XX 字符的路径
  第 2 个参数除了可以写返回的随机数据,还可以是一个 callback 进行处理,再将结果返回给前台
*/ 
Mock.mock(/test.html/, (options) => {
	// ...
});
/*
	GET 请求的参数被放在 options 的 url 属性上
  POST 请求的参数在 options 的 body 属性上
*/ 
Mock.mock(/test.html/, (options) => {
  console.log(options); // {url: "./test.html?name=zhangsan&password=123", type: "GET", body: null}
  console.log(options.url); // ./test.html?name=zhangsan&password=123
});

既然都得到 ./test.html?name=zhangsan&password=123 了,取出账号 "zhangsan" 和密码 "123" 就很简单了

Mock.mock(/test.html/, (options) => {
  
  // 拆分 options.url 的值: ./test.html?name=zhangsan&password=123
  
  let userContent = options.url.split('?')[1].split('&');  // ['name=zhangsan', 'password=123']
  let username = userContent[0].split('=')[1], // zhangsan
      password = userContent[1].split('=')[1]; // 123
  
  // 如果是本地存储,就以本地存储的形式去获取、判断,这里只做简单的变量判断
  let result = users.some(item => item.username == username && item.password == password);
  return result;
});

整合

// 用户信息如果存在 localStorage 就使用 localStorage 的存取
const users = [
  { name: 'zhangsan', password: '123' },
  { name: 'lisi', password: '456' }
];

Mock.mock(/test.html/, function (options) {
  let userContent = options.url.split('?')[1].split('&'); 
  let username = userContent[0].split('=')[1],
      password = userContent[1].split('=')[1];
  let result = users.some(item => item.username == username && item.password == password);
  // 模拟后台操作,返回结果给前台
  return result;
});

btn.onclick = function () {
  let xhr = new XMLHttpRequest();
  xhr.open('GET', `./test.html?username=${txt.value}&password=${pwd.value}`);
  xhr.send();
  xhr.onreadystatechange = function () {
    if (xhr.readyState == 4 && xhr.status == 200) {
      let data = JSON.parse(xhr.responseText); // 回来的数据为 string
      if(data){
        console.log('登录成功');
      }else{
        console.log('登录失败');
      }
    }
  }
}

如果是 POST 请求,发送的数据去观察 options.body ,不贴答案了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值