Mockjs原理简析

Posted vcxiaohan2

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mockjs原理简析相关的知识,希望对你有一定的参考价值。

前言

有一个前后端分离的项目用到过Mockjs,后端提供了数据格式,前端通过模拟接口的返回数据,进行页面的渲染,有一段时间,百思不得其解,这个插件是怎么把ajax请求给拦下来的,网上搜索了一番,资料甚少,未果。
后来有一天,不知道怎么的突然想到,如果把ajax方法请求改写了,在发送请求之前提供一个回调是不是能实现这个功能?

思路

  • 准备环境
    • 从最方便的jquery入手,打算改写$.ajax
  • 需要解决的问题主要有
    • $.ajax即将被改写,所以要自己实现一个发送请求的xhr方法(又懒得写封装的ajax方法,于是把$.ajax缓存起来,以待后用)
    • 如何去匹配将被拦截的请求地址
    • 拦截了请求之后,如何把预先准备好的数据当做请求成功后的数据
  • 代码实现

    let Mock = 
      // 存储匹配规则
      rules: new Map(),
      // 缓存ajax方法
      ajax: $.ajax,
      mock(url, data) 
        this.rules.set(url, data)
      
    
    
    // 改写ajax方法
    $.ajax = function(options) 
      Mock.ajax(
        url: options.url,
        beforeSend(XHR) 
          let data = Mock.rules.get(options.url)
          // 找到规则拦截请求,并执行回调(return false时会拦截请求)
          data && options.success(data)
          return !data
        ,
        success(data) 
          // 找不到规则,正常发送请求
          options.success(data)
        
      )
    
    
    // 测试
    Mock.mock('/a', 
      a: 1,
      b: 2
    )
    $.ajax(
      url: '/a',
      success(data) 
        console.log(data, 1)
      
    )
    $.ajax(
      url: '/b',
      success(data) 
        console.log(data, 2)
      
    )
  • 功能检测
    • 以上代码可直接拷贝至控制栏运行,我们可以看到只发送了b请求,a请求被拦截了下来,同时我们也能拿到所预期的数据
    • 至于Mockjs随机数据的功能,我们暂不考虑

总结

  • 之后我也粗略看了下Mockjs源码,它也是改写了jquery和zepto的$.ajax方法所实现,这就意味着如果是自己用原生js封装的ajax方法,是不能拦截的
    如下,是一个原生js的ajax方法,有兴趣可以自己去检测一下:

    var Ajax=
        get: function(url, fn) 
            var xhr = new XMLHttpRequest();  // XMLHttpRequest对象用于在后台与服务器交换数据          
            xhr.open('GET', url, true);
            xhr.onreadystatechange = function() 
                if (xhr.readyState == 4 && xhr.status == 200 || xhr.status == 304)  // readyState == 4说明请求已完成
                    fn.call(this, xhr.responseText);  //从服务器获得数据
                
            ;
            xhr.send();
        ,
        post: function (url, data, fn)          // datat应为'a=a1&b=b1'这种字符串格式,在jq里如果data为对象会自动将对象转成这种字符串格式
            var xhr = new XMLHttpRequest();
            xhr.open("POST", url, true);
            xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");  // 添加http头,发送信息至服务器时内容编码类型
            xhr.onreadystatechange = function() 
                if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304))   // 304未修改
                    fn.call(this, xhr.responseText);
                
            ;
            xhr.send(data);
        
    
  • 很多公司源于方便已经提供了自己专门的mock服务平台,以供前端开发者更快捷的模拟数据,搭建教程我会在另一篇文章中讲述

以上是关于Mockjs原理简析的主要内容,如果未能解决你的问题,请参考以下文章

CoordinatorLayout原理的简析

cgroup原理简析:进程调度

Flutter跨组件共享状态的利器Provider简析

Flutter跨组件共享状态的利器Provider框架简析

.NET Core 3.0 可卸载程序集原理简析

简析散光的成因,以及什么是散光的度数和轴位?