转载

mock.js-无需等待,让前端独立于后端进行开发

概述

  • 首先啦,我不认识mock.js的作者,带着需求找到mock.js让我觉得很惊艳。
  • 相对于其他同类的框架的实现,mock.js超出了我的意料。
    • 基于 数据模板 生成模拟数据。
    • 基于 HTML模板 生成模拟数据。
    • 拦截并模拟 ajax 请求。
  • 是的,mock.js只做上述的几件事,但做的足够出色。

解决的问题

开发时,后端还没完成数据输出,前端只好写静态模拟数据。

  • 数据太长了,将数据写在js文件里,完成后挨个改url。
  • 某些逻辑复杂的代码,加入或去除模拟数据时得小心翼翼。
  • 想要尽可能还原真实的数据,要么编写更多代码,要么手动修改模拟数据。
  • 特殊的格式,例如IP,随机数,图片,地址,需要去收集。
  • 超烂的破网速…

使用过程中遇到的问题及相应解决方案

1.项目基于seajs开发,所以不能根据 URL 中是否含有参数 mock 动态加载数据模板。

  • 代码示例:
    ~location.search.indexOf('mock') && require('mock/index');
  • 背景:为了灵活控制是否启用模拟数据我们会在url上新增mock参数,有mock就会加载数据模板,没有就不会加载,但是上面代码没有达到这一目的,不管url上有无mock参数,都会加载数据模板
  • 原因:因为seajs内部的预加载机制,只要代码里进行了require某个文件,它都会解析文件依赖关系,从而下载这些文件;
  • 解决办法:

    var module = ['page/index/index']; if (~location.search.indexOf('mock'))     module.push('mock/index');  seajs.use("business/router", function (router) {     router.ready(function (params, index) {         index.init(params);     }, module); });

    这里,我们在html页面入口部分,根据url是否含有mock来动态选择需要异步加载的模块,从而解决了这一问题。

2.项目使用了net.js对ajax请求进行了一层封装,无法拦截ajax请求。

  • 代码示例:
    Mock.mock('a.json', {   result: 0,   errmsg: 'ok',   data: {    'list|0-10': [{     'icon': '@image',     'nick': '@name',     'inviteTime': '@date'    }],    'hasMore|0-1': 1,    'invitePeopleNum|1-50': 20,    'getAwardNum|10-600': 12,    'hasAward|0-1': 1   }  });  net.ajax({   url: 'a.json',   data: {    module: "invite_chest_box",    method: "GetInviteList",    param: {     "tt": "2",     "appId": "1000001034",     "pageNo": 0,     "pageCount": 10    }   },   cache: false,   dataType: 'json',   success: function (json) {  //成功之后回调    console.log(json)   }  }); 
  • 背景:mock.js因为默认内置jQuery、Zepto、KISSY的拦截ajax请求,由于我们项目中对ajax请求专门做了一层封装,所以无法拦截ajax请求。
  • 解决方案:

    var net = require('util/net'); Mock.mockjax(net);

    调用mackjax方法,将拦截操作注入net.ajax中,从而拦截ajax才会生效。

3.一个项目cgi名称和模块名相同,不同接口使用method来区分,通过method无法区分不同接口和拦截ajax请求。

  • 代码示例:

    Mock.mock(/getInviteList/, {   result: 0,   errmsg: 'ok',   data: {    'list|0-10': [{     'icon': '@image',     'nick': '@name',     'inviteTime': '@date'    }],    'hasMore|0-1': 1,    'invitePeopleNum|1-50': 20,    'getAwardNum|10-600': 12,    'hasAward|0-1': 1   }  });  $.ajax({   url: 'http://gift.gamecenter.qq.com/cgi-bin/gc_invite_chest_box_fcgi',   data: {    module: "invite_chest_box",    method: "GetInviteList",    param: {     "tt": "2",     "appId": "1000001034",     "pageNo": 0,     "pageCount": 10    }   },   cache: false,   dataType: 'json',   success: function (json) {  //成功之后回调    console.log(json)   }  }); 

    Mock.mock的第一个参数为匹配的规则,可以是字符串,也可以是正则,这里我们用cgi的method来匹配当前cgi,但是可惜的是没有匹配到

  • 原因: mock.js-无需等待,让前端独立于后端进行开发

查看源码我们发现,当匹配规则为字符串时,匹配规则必须要与请求url完全一致才行,当匹配规则为正则时,需要在请求url上检查是否存在满足的匹配,所以不管是字符串匹配还是正则匹配,都只是在url上查找匹配,并不能匹配data内部的参数(比如method:GetInviteList)

  • 解决方案: mock.js-无需等待,让前端独立于后端进行开发

这里将options里面的data对象也都纳入检查匹配的范畴,都是将两处的匹配检查都改成了正则匹配,都是忽略字母大小写,这样,我们就可以根据data内部的任意参数来匹配不同的cgi请求,大大提高了匹配的灵活性。

查看响应的结果

{  "result": 0,  "errmsg": "ok",  "data": {   "list": [    {     "icon": "http://dummyimage.com/120x600",     "nick": "Charles Hernandez",     "inviteTime": "1988-09-26"    },    {     "icon": "http://dummyimage.com/120x60",     "nick": "Linda Garcia",     "inviteTime": "1991-09-14"    }   ],   "hasMore": 0,   "invitePeopleNum": 45,   "getAwardNum": 511,   "hasAward": 0  } } 
正文到此结束
Loading...