xe-ajax-mock 前端虚拟服务

最新版本见 Github,点击查看历史版本

基于 XEAjax 扩展的 Mock 虚拟服务插件;对于前后端分离的开发模式,ajax+mock 使前端不再依赖后端接口开发效率更高。

CDN

使用 script 方式安装,XEAjaxMock 会定义为全局变量
生产环境请使用 xe-ajax-mock.min.js,更小的压缩版本,可以带来更快的速度体验。

cdnjs 获取最新版本

点击浏览已发布的所有 npm 包源码

<script src="https://cdn.jsdelivr.net/npm/xe-ajax-mock/dist/xe-ajax-mock.js"></script>

unpkg 获取最新版本

点击浏览已发布的所有 npm 包源码

<script src="https://unpkg.com/xe-ajax-mock/dist/xe-ajax-mock.js"></script>

AMD

require.js

// require 配置
require.config({
  paths: {
    // ...,'xe-ajax': './dist/xe-ajax.min','xe-ajax-mock': './dist/xe-ajax-mock.min'
  }
})

// ./mock/index.js 配置文件
define(['xe-ajax','xe-ajax-mock'],function (XEAjax,XEAjaxMock) {
  // 安装
  XEAjax.use(XEAjaxMock)
})

NPM

npm install xe-ajax xe-ajax-mock --save

NodeJS

const XEAjaxMock = require('xe-ajax-mock')

ES6 Module import

import XEAjaxMock from 'xe-ajax-mock'

ES6 Module import

import { GET,POST,PUT,DELETE,JSONP } from 'xe-ajax-mock'

API

提供的便捷方法:

  • Mock( defines,options )
  • Mock( path,method,response,options )
  • HEAD( path,options )
  • GET( path,options )
  • POST( path,options )
  • PUT( path,options )
  • DELETE( path,options )
  • PATCH( path,options )
  • JSONP( path,options )

入参

  • path(字符串)请求地址,占位符{key}支持动态路径: 例如: /api/list/{key1}/{key2} 匹配 /api/list/10/1
  • method(字符串)请求方法 | 默认GET
  • response(对象/方法(request,context))数据或返回数据方法,格式:{status: 200,statusText: 'OK',body: {},headers: {}}
  • options (可选,对象)参数

options 参数说明

参数 类型 描述
baseURL String 基础路径 默认上下文路径
template Boolean 启用数据模板自动编译,可以设置true,false 默认false
pathVariable Boolean 启用路径参数类型自动解析,可以设置false,true,auto 默认true
timeout String 模拟请求时间 默认'20-400'
jsonp String jsonp入参属性名 默认callback
headers Object 设置响应头
error Boolean 控制台输出错误日志,false true
log Boolean 控制台输出请求详细日志,false false

全局参数设置

import XEAjaxMock from 'xe-ajax-mock'

XEAjaxMock.setup({
  baseURL: 'http://xuliangzhan.com',template: true,pathVariable: 'auto',timeout: '100-600',headers: {
    'Content-Type': 'application/json; charset=utf-8'
  },error: true,log: true
})

数据模板 - 基本语法

数值

[key]|number

import { template } from 'xe-ajax-mock'

template({
  'num|number': '123'
})
// 结果: {num: 123}

布尔值

[key]|boolean

import { template } from 'xe-ajax-mock'

template({
  'flag1|boolean': 'true','flag2|boolean': 'false'
})
// 结果: {flag1: true,flag2: false}

生成一个或多个值

[key]|array([min]-[max])

import { template } from 'xe-ajax-mock'

template({
  'region|array(1-5)': '值'
})
// 结果: {region: ['值','值','值']}

template({
  'region|array(1)': ['深圳','北京','上海','广州']
})
// 结果: {region: ['深圳']}

template({
  'region|array(1-3)': ['深圳','广州']
})
// {region: ['深圳','北京']}

随机生成一个或多个值

[key]|random([min]-[max])

import { template } from 'xe-ajax-mock'

template({
  'region|random(1-5)': '值'
})
// 结果: {region: ['值','值']}

template({
  'region|random(1)': ['深圳','广州']
})
// 结果: {region: '深圳'}

template({
  'region|random(1-3)': ['深圳','广州']
})
// 结果: {region: ['上海','北京']}

对象

import { template } from 'xe-ajax-mock'

template({
  'id|number': '1','name': 'test 1','region|array(1)': ['深圳','广州'],'active|boolean': '1'
  'age|number': '30'
})
// 结果: {id: 1,name: 'test 1',region: ['深圳'],active: true,age: 30}

数组

import { template } from 'xe-ajax-mock'

template(['{{ random.repeat("随机产生一段文本",10,20) }}','{{ random.date("2018-03-04","2018-03-20") }}'])
// 结果: ['"产机文机文生生一产产随本生随随段段一本"','2018-03-13 14:52:02']

template([{
  'id|number': '1','name': 'test1','active|boolean': '0','age|number': '30'
}])
// 结果: [{id: 1,name: 'test 0',region: ['上海'],active: false,age: 30}]

内置属性

$size 获取数组大小
$index 获取数组索引
$params 获取查询参数
$body 获取提交参数
$pathVariable 获取路径参数

import { template } from 'xe-ajax-mock'

template({
  'result|array(1-5)': {
    'id|number': '{{ $index }}','size|number': '{{ $size }}','name': '{{ $params.name }}','password': '{{ $body.password }}'
  }
})
// 结果:
// {
//   age: {pageSize: 10,currentPage: 1},//   result: [{id: 0,size: 2,name: 'test',password: ''},{id: 1,password: ''}]
// }

直接输出对应值

!return 当对象中只有一个属性 !return 时直接输出对应值

import { template } from 'xe-ajax-mock'

template({
  '!return': {
    'id|number': '1','name': 'test {{ $index }}','active|boolean': '{{ random.num(0,1) }}','age|number': '{{ random.num(18,60) }}'
  }
})
// 结果: {id: 1,age: 30}

template({
  '!return|array(1-2)': {
    'id|number': '{{ $index+1 }}',60) }}'
  }
})
// 结果:
// [{id: 1,age: 30},// {id: 2,region: ['北京'],age: 42}]

数据模板 - 高级语法

随机数值

random.num(min,max)

import { template } from 'xe-ajax-mock'

template({
  'age': '{{ random.num(18,60) }}'
})
// 结果: {age: '30'}

template({
  'ip': '{{ random.num(1,254) }}.{{ random.num(1,254) }}'
})
// 结果: {ip: '147.136.43.175'}

template({
  'color': 'rgb({{ random.num(100,120) }},{{ random.num(140,180) }},160) }})'
})
// 结果: {color: 'rgb(242,121,132)'}

根据内容随机生成值

random.repeat(array|string,min,max)

import { template } from 'xe-ajax-mock'

template({
  'describe': '{{ random.repeat("随机产生一段文本",200) }}'
})
// 结果: {describe: '段生随本段段随机本一段段机本本一本段段随机'}

template({
  'email': '{{ random.repeat("abcdefg",5,20) }}@163.{{ random.repeat(["com","net"],1) }}'
})
// 结果: {email: 'abcfdgecee@163.com'}

随机时间戳

random.time(startDate,endDate)

import { template } from 'xe-ajax-mock'

template({
  'datetime': '{{ random.time("2018-03-04") }}'
})
// 结果: {datetime: '1520092800000'}

template({
  'datetime': '{{ random.time("2018-03-04","2018-03-20") }}'
})
// 结果: {datetime: '1520611200000'}

随机日期

random.date(startDate,endDate,format)

import { template } from 'xe-ajax-mock'

template({
  'dateStr': '{{ random.date("2018-03-04") }}'
})
// 结果: {dateStr: '2018-03-04'}

template({
  'dateStr': '{{ random.date("2018-03-04",null,"yyyy-MM-dd HH:mm:ss.S") }}'
})
// 结果: {dateStr: '2018-03-04 00:00:00.0'}

template({
  'dateStr': '{{ random.date("2018-03-04","2018-03-20") }}'
})
// 结果: {dateStr: '2018-03-10'}

template({
  'dateStr': '{{ random.date("2018-03-04","2018-03-20","yyyy-MM-dd HH:mm:ss.S") }}'
})
// 结果: {dateStr: '2018-03-10 10:30:20.500'}

分页配置

import { template } from 'xe-ajax-mock'

// Mock 配置:GET('http://xuliangzhan.com/api/user/list/{pageSize/{currentPage}')
// 请求调用:getJSON('api/user/list/10/1',{name: 'test'})
template({
  "page": {
    "currentPage|number": "{{ $pathVariable.currentPage }}","pageSize|number": "{{ $pathVariable.pageSize }}","totalResult|number": "{{ random.num(100,200) }}"
  },"result|array({{ $pathVariable.pageSize }})": {
    "id|number": "{{ $index+1 }}","name": "test {{ $index }}","region|random(1)": ["深圳","北京","上海","广州"],"roles|array(1-3)": ["admin","developer","tester","designer"],"isLogin|boolean": "{{ random.num(0,1) }}","email": "{{ random.repeat('abcdefg',20) }}@qq.{{ random.repeat(['com','net'],"color": "rgb(120,160) }})","ip": "192.168.{{ random.num(1,254) }}","age|number": "{{ random.num(18,60) }}","password": "{{ random.num(100000,999999) }}","describe": "{{ random.repeat('描述信息',200) }}","createDate": "{{ random.date('2018-01-01','2018-06-20') }}","updateTime": "{{ random.time('2018-01-01','2018-06-20') }}"
  }
})

模板混合函数

template.mixin({})

import { template } from 'xe-ajax-mock'

template.mixin({
  format (str) {
    return '格式化:' + str
  }
})

template({
  'val': '{{ format("2018-01-01") }}'
})
// 结果: {val: '格式化:2018-01-01'}

示例

Mock

import { Mock } from 'xe-ajax-mock'

Mock([{
  path: '/api/user',children: [{
    method: 'GET',path: 'list',response: {
      '!return|array(1-3)': {
        'id|number': '{{ $index+1 }}','name': '{{ random.repeat("随机生成名字",4,20) }}'
      }
    },},{
    method: 'POST',path: 'submit',response: {msg: 'success'},{
    method: 'DELETE',path : 'delete/{id}',response (request,response) {
      response.status = 500
      response.body = {msg: 'error'}
      return response
    }
  ]
}])

HEAD

import { HEAD } from 'xe-ajax-mock'

HEAD('/api/user/head',null)

GET

import { GET } from 'xe-ajax-mock'

GET('/api/user/list',{msg: 'success'})

GET('/api/user/list',(request,response) => {
  response.status = 200
  response.statusText = 'OK'
  response.body = {
    '!return|array(1-3)': {
      'id|number': '{{ $index+1 }}',20) }}'
    }
  }
  return response
})

GET('/api/user/list/{pageSize}/{currentPage}',context) => {
  response.body = {
    'page': {
      'currentPage|number': '{{ $pathVariable.currentPage }}','pageSize|number': '{{ $pathVariable.pageSize }}'
    },'result|array(2-5)': {
      'id|number': '{{ $index+1 }}',20) }}'
    }
  }
  return response
})

POST

import { template,POST } from 'xe-ajax-mock'

POST('/api/user/save',{msg: 'success'})

POST('/api/user/save',response) => {
  response.body = {msg: 'success'}
  return response
})

POST('/api/user/save',response) => {
  // 模拟后台逻辑 对参数进行校验
  if (request.params.id) {
    response.body = {msg: 'success'}
  } else {
    response.status = 500
    response.body = {msg: 'error'}
  }
  return response
})

PUT

import { PUT } from 'xe-ajax-mock'

PUT('/api/user/update',{msg: 'success'})

PUT('/api/user/update',response) => {
  response.status = 500
  response.body = {msg: 'error'}
  return response
})

DELETE

import { DELETE } from 'xe-ajax-mock'

DELETE('/api/user/delete/{id}',{msg: 'success'})

DELETE('/api/user/delete/{id}',response) => {
  response.body = {msg: 'success'}
  return response
})

PATCH

import { PATCH } from 'xe-ajax-mock'

PATCH('/api/user/update',{msg: 'success'})

JSONP

import { JSONP } from 'xe-ajax-mock'

JSONP('http://xuliangzhan.com/jsonp/user/message',{msg: 'success'})

JSONP('http://xuliangzhan.com/jsonp/user/message',response) => {
  response.body = {
    '!return|array(1-3)': {
      'id|number': '{{ $index+1 }}',20) }}'
    }
  }
  return response
}, {jsonp: 'cb'})

AMD 使用方式

define([
  'xe-ajax-mock'
],function (XEAjaxMock) {

  XEAjaxMock.GET('/api/user/list1',{msg: 'success'})
  XEAjaxMock.GET('/api/user/list2',function (request,response) {
    response.body = {
      '!return|array(1-3)': {
        'id|number': '{{ $index+1 }}',20) }}'
      }
    }
    return response
  })

  // 支持链式写法
  XEAjaxMock
  .GET('/api/user/list3',{msg: 'success'})
  .POST('/api/user/save1',response) {
    response.body = {msg: 'success'}
    return response
  })
  .POST('/api/user/save2',response) {
    return response.require('mock/json/api/user/save/data.json')
  })
})

混合函数

文件 ./customs.js

import { POST } from 'xe-ajax-mock'

export function POST2 (path,options) {
  return POST(path,{message: '成功'},options)
}

示例 ./main.js

import { Mock } from 'xe-ajax-mock'
import customs from './customs'

Mock.mixin(customs)

Mock.POST2('/api/user/save')

示例

XEAjaxMock 对虚拟服务目录结构不限制,当虚拟服务配置越来越多时,统一目录结构可维护性会更好

项目示例

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


$.AJAX()方法中的PROCESSDATA参数 在使用jQuery的$.ajax()方法的时候参数processData默认为true(该方法为jQuery独有的) 默认情况下会将发送的数据序列化以适应默认的内容类型application/x-www-form-urlencoded 如果想发送不
form表单提交的几种方式 表单提交方式一:直接利用form表单提交 html页面代码: &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;meta charset=&quot;UTF-8&quot; /&gt; &lt;title&gt;Ins
文章浏览阅读1.3k次。AJAX的无刷新机制使得在注册系统中对于注册名称的检测能即时显示。常见的用户注册是用户输入用户名,后台程序检测数据库中用户名是否重复而做出注册的成功与失败之提示(当用户注册重名时将返回重新注册),或者稍微人性化一点就是在用户名文本框后添加一个检测按钮,让用户检测后再做注册。以上操作,对于用户体验方面来说是比较“差劲”的,一个很好的用户体验就是:当用户输入完注册用户名后,Web系统应能即时检查并即时_用户注册 实时异步检测
文章浏览阅读1.2k次。 本文将解释如何使用AJAX和JSON分析器在客户端和服务器之间创建复杂的JSON数据传输层。一、 引言毫无疑问,AJAX已经成为当今Web开发中一种强有力的用户交互技术,但是它的许多可能性应用仍然鲜为人知。在本文中,我们将来共同探讨如何 使用JavaScript对象标志(JSON)和JSON分析器在服务器和客户端AJAX引擎之间创建复杂而强有力的JSON数据传输层。我们将_ajax技术可行性
文章浏览阅读2.2k次。/************************** 创建XMLHttpRequest对象 **************************/function CreateRequest(){ var xmlObj = null; try { xmlObj = new XMLHttpRequest(); } catch(e) {
文章浏览阅读3.7k次。在ajax应用中,通常一个页面要同时发送多个请求,如果只有一个XMLHttpRequest对象,前面的请求还未完成,后面的就会把前面的覆盖 掉,如果每次都创建一个新的XMLHttpRequest对象,也会造成浪费。解决的办法就是创建一个XMLHttpRequset的对象池,如果池里有 空闲的对象,则使用此对象,否则将创建一个新的对象。下面是我最近写的一个简单的类:* XMLHttpReques_xmlhttprequest发送多个请求
文章浏览阅读3.1k次。Ajax 同一页面如何同时执行多个 XMLHTTP 呢,比如博客页,需要同时利用 Ajax 读取作者信息、文章信息、评论信息……我们的第一反应可能是创建多个全局 XMLHTTP 对象,但这并不现实。其实实现方式非常简单,就是给 onreadystatechange 对应的回调函数加上参数,以下代码是解决方案中一个函数中的一段代码。xmlhttp.open("GET", "ajax_proc_ajax响应多个mxl文件
文章浏览阅读1.5k次。数据岛指的是存在Html网页中的xml代码段,它在Html中形成了一个数据的集合,数据岛允许我们在Html网页中集成xml,对xml编写脚本.数据岛有它特有的形式,由标记xml开始,在开始标记中要有一个ID属性,用于指定该指定数据岛的名称。 (当然要以/xml结束).元素xml包含的内容就是xml代码。数据岛也分为2种:1)内嵌的数据岛形式2)外嵌的数据岛形式说了那么多废话,还_数据中岛计算模式
文章浏览阅读2.1k次。AJAX 流行之后,总想好好学习一下。但是众多的框架实在难以选择。说明一下 ASP.NET AJAX 并不包括在 AJAX 框架之中。刚开始学了 JQuqery, 众多的 $get(),...等等符号早已把我搞晕了。暂时就放弃了。后来学习 ASP.NET AJAX ,在微软的领导下,逐渐由服务器端转向客户端编程。 激起我客户端编程的兴趣,才想起学习一下了 Jquery. 随着WEB2._jquery ajax asp.net 认证
文章浏览阅读1.7k次。前段时间在用google map api的函数库的时候,发现里面的downloadUrl函数非常好用,所以自己写了一个。用腻了那些什么框架什么池,到头来发现越简单的东西越是适合我这种懒人。downloadUrl(url, callback, data);参数说明: url不用说了; callback是回调函数,函数调用的时候会有两个参数:data, responseCode,data就_xmlhttprequest downloadurl
文章浏览阅读956次。前些时间写了几篇关于XMLHTTP运用的实例.(可以到http://dev.csdn.net/user/wanghr100看之前的几编关于XMLHTTP的介绍.)近来看论坛上经常有人提问关于如何无刷新,自动更新数据.传统上,我们浏览网页,如果加入最新的数据.只能是等我们重新向服务器端请求时才能显示出来.但是,对于一些时效性很强的网站.传统的这种做法是不能满足的.我们可以让程序自动刷新.定时_后端xml怎么实现数据有救新增,没有就更新
文章浏览阅读3.3k次。 XMLHttpRequest调用XMLHttpRequest Call ●●●调用,回调,下载,抓取,实时,查询,远程通信(Remoting),远程通信脚本(RemoteScripting),同步,上传,XMLHttpRequest图6-2:XMLHttpRequest调用 目标故事Reta正在一个批发商网站上购买商品。每次她添加一个商品到购物车时,web站点发出_createxmlhttpre
文章浏览阅读1.3k次。function clearitem(){ var drp1 = document.getElementById("drp1"); while(drp1.options.length>0) { drp1.options.remove(0); } }//动态更改方法(根据城市代码取得该市商业区并添加到DropDownList中_dropdownlist根據動態變化
文章浏览阅读1.9k次。因為 Json.net 是有附原始碼的,他也附了單元測試的專案,底下是我額外增加的UnitTest,我的目標就是讓底下的測試可以pass,而且原來的Test 也要都能通過。 ValueTypeTest.csusing System;using NUnit.Framework;namespace Newtonsoft.Json.Test { [TestFixture] public cl_vb 無效的 json 基本型別
文章浏览阅读844次。利用XMLHTTP无刷新获取数据. 客户端和服务器端数据的交互有几种方法.1.提交,通过提交到服务器端.也称"有刷新"吧.2.通过XMLHTTP无刷新提交到服务器端,并返回数据.也称"无刷新"吧.利用XMLHTTP我们可以实现很多很强大的应用.这文章主要介绍它的一些简单的应用.附:因为XMLHTTP是IE5.0+支持的对象.所以你必须要有IE5.0+才能看到效果.client.htm_xmlhttp取源码没有更新
文章浏览阅读1.8k次。Json.Net 無法序列基本型別(string, int),Asp.Net Ajax 無法正確序列日期,AjaxPro序列出我不想要的_type字串 1. Json.Net 是我最常使用的序列/反序列json套件,標榜速度快,對於一對多關係的object 也都能正常運作, 己能滿足我平日的需要,但前幾天突然有個情況,我要序列的是一個泛型參數,該參數不一定是物object型別,有可能是st_token string in state start
文章浏览阅读1.3k次。转载自:http://www.cnblogs.com/JeffreyZhao/archive/2007/01/31/update_the_updatepanels_by_js.html众 所周知,UpdatePanel是通过Trigger来更新的。被设定为Trigger的控件在PostBack之后会被客户端所截获,并且使用 XMLHttpRequest对象发送内容,然后服务器端由ScriptMan_web.ui.updatepanel 和 updatepanel 的区别
文章浏览阅读1.9k次。有些时候,只是需要更新页面的一个部分甚至只是更新中间的几个数据却需要从服务器DOWN整个页面,导致各种资源的浪费。使用数据岛技术可以很好的解决这个问题:通过定时器或用户事件触发数据岛(XML对象)象服务器获取数据,在数据获取完成后,适时更新相关数据。示例HTML部分:http://localhost/WebService/LoadData/FeaturedService.asmx/GetScore_web数据岛
文章浏览阅读1k次。在页面上使用ActiveXObject的代价是很大的,如果我们的无刷新页面使用xmlhttp技术,我们或许需要频繁的建立xmlhttp对象,当然 我们也可以使用全局变量来cache一个xmlhttp对象实例。但是这样的方法适合于同步方式xmlhttp通信,而对于异步方式xmlhttp通信将 会出现问题。由于没有了进程的堵塞,用户可能再次调用同一个xmlhttp实例,如果这时前一个通信未完成,那么就
文章浏览阅读998次。 by Lokesh Dhakar 译: croc查看原文概要:Lightbox JS 是一个简单而又谦恭的用来把图片覆盖在当前页面上的脚本. 它能被快速安装并且运作于所有流行的浏览器.最新更新 Version 2.0 图片集: 分组相关的图片并且能轻松的导航它们 视觉特效: 奇特的自适应调整 向后兼容: yes! 点击这里查看实例_on lightbox 2 by lokesh dhakar