index.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /**
  2. * @created by pan
  3. * @updated by helin3 2019-04-05
  4. * @description Mock数据模拟入口
  5. * 1) 开发模式,调用Mock入口见: /vue.config.js devServer.after
  6. * 2) 生产模式,调用Mock入口见: /src/main.js
  7. */
  8. import Mock from 'mockjs'
  9. import registers from './registers'
  10. /*eslint camelcase:0 */
  11. /*eslint no-div-regex:0 */
  12. /*eslint prefer-template:0 */
  13. /*eslint prefer-rest-params:0*/
  14. /*eslint consistent-return:0*/
  15. /**
  16. * URL 参数转对象
  17. * @param {String} url 带问号URL
  18. * eg. ?username=aleynhe&password=123456
  19. * eg. username=aleynhe&password=123456
  20. * @returns {Object}
  21. */
  22. const param2Object = url => {
  23. const search = url.split('?')[1]
  24. if (!search) {
  25. return {}
  26. }
  27. return JSON.parse('{"' +
  28. decodeURIComponent(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"').replace(/\+/g, ' ') +
  29. '"}')
  30. }
  31. /**
  32. * 模拟响应数据,用于导出开发环境mock api响应模拟
  33. * 基于 express 服务模拟
  34. * @param {*} url
  35. * @param {*} type
  36. * @param {*} respond
  37. */
  38. const responseFake = (url, type, respond) => {
  39. return {
  40. url: new RegExp(`${url}`),
  41. type: type || 'get',
  42. response(req, res) {
  43. res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
  44. }
  45. }
  46. }
  47. /**
  48. * 前端Mock模拟,请谨慎使用,它将重新定义xmlhttprequest,这将导致许多第三方库失效(如进度事件)。
  49. * 生产(测试/演示)环境,自动注册所有mock api
  50. * 调用入口见:src/main.js
  51. */
  52. export function mockXHR() {
  53. // 修复在使用 MockJS 情况下,设置 withCredentials = true,且未被拦截的跨域请求丢失 Cookies 的问题
  54. // https://github.com/nuysoft/Mock/issues/300
  55. Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
  56. Mock.XHR.prototype.send = function() {
  57. if (this.custom.xhr) {
  58. this.custom.xhr.withCredentials = this.withCredentials || false
  59. if (this.responseType) {
  60. this.custom.xhr.responseType = this.responseType
  61. }
  62. }
  63. this.proxy_send(...arguments)
  64. }
  65. /**
  66. * Mock XHR模式转Express响应,保证开发模式与生产模式,Mock api接口一致
  67. * @param {*} respond
  68. */
  69. function XHR2ExpressReqWrap(respond) {
  70. return function(options) {
  71. let result = null
  72. if (respond instanceof Function) {
  73. const { type, url } = options
  74. let { body } = options
  75. // 先按JSON字符串来转对象
  76. // 若出错,则按URL来转对象;若还是出错,则传递原参数值
  77. try {
  78. body = JSON.parse(body)
  79. } catch (e) {
  80. try {
  81. body = param2Object('?' + body)
  82. } catch (err) {
  83. window.console.error('Mocks XHR2ExpressReqWrap request data format error.')
  84. return
  85. }
  86. }
  87. // https://expressjs.com/en/4x/api.html#req
  88. result = respond({
  89. method: type,
  90. body: body,
  91. query: param2Object(url)
  92. })
  93. } else {
  94. result = respond
  95. }
  96. return Mock.mock(result)
  97. }
  98. }
  99. // 循环注册mock api
  100. for (const i of registers) {
  101. Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
  102. }
  103. }
  104. /**
  105. * 开发环境Mock api自动注册(通过express注册)
  106. * 详见:/mocks-server.js export
  107. */
  108. export default registers.map(route => {
  109. let type = route.type || 'get'
  110. type = (`${type}`).toLowerCase()
  111. return responseFake(route.url, type, route.response)
  112. })