分割线如下是原来写的,其实mock的原理很是简单,就是拦截请求“转发”到本地文件,所谓转发,其实就是读取本地mock文件,并以json或者script等格式返回给浏览器。以前的实现方式有一个问题,由于mock文件是require进来的,因此每当修改mock文件后,须要重启服务,其实换个思路,咱们从文件里面读数据不久行了么?javascript
//mockAPI.js var fs = require('fs'); var path = require('path'); var mockbase = path.join(__dirname, 'mock'); var mockApi = function(res, pathname, paramObj, next) { switch (pathname) { case '/api/vote': var data = fs.readFileSync(path.join(mockbase, 'vote.json'), 'utf-8'); // res.setHeader('Content-Type', 'application/json'); res.setHeader('Content-type', 'application/javascript'); res.end(paramObj.callback + '(' + data + ')'); return ; case '/api/getUserInfo': var data = fs.readFileSync(path.join(mockbase, 'getUserInfo.json'), 'utf-8'); res.setHeader('Content-type', 'application/javascript'); res.end(paramObj.callback + '(' + data + ')'); return ; case '/api/apply': var data = fs.readFileSync(path.join(mockbase, 'apply.json'), 'utf-8'); res.setHeader('Content-type', 'application/javascript'); res.end(paramObj.callback + '(' + data + ')'); return ; default: ; } next(); }; module.exports = mockApi;
//gulpfile.js var mockApi = require('./mockApi'); ... gulp.task('webserver', function() { gulp.src('./app') .pipe(webserver({ ... middleware: function(req, res, next) { var urlObj = url.parse(req.url, true), method = req.method, paramObj = urlObj.query; // mock数据 mockApi(res, urlObj.pathname, paramObj, next); } })); });
知道了原理后,不管是ajax仍是jsonp,你想怎么mock就怎么mock。另外能够利用webserver的proxies选项把请求代理到线上(经过代理解决跨域),这样就不用本地的mock文件,而是直接请求线上或beta环境的接口了。前端
最近在使用gulp构建前端项目,这个基于node流并崇尚“编程而非配置”的工具立马让我爱上了它。由于以前使用公司的fekit,因此在使用gulp时就会想和fekit去比较,看看fekit的功能用gulp如何实现。fekit在先后端分离上作得很是好,基本能让前端开发人员脱离后端环境进行开发,其中很重要的一个功能就是接口数据的mock。简单地讲,就是转发ajax请求到本地的json(或mockjson)文件,这样咱们在代码里写真实的url(而不是写一个本地的json文件地址),而后借由fekit转发到本地的json文件,这样就轻松实现了接口的mock。 java
在此次项目中,我一样有这样的需求,举个例子,我须要把/api/orders
转发到/mock/orders.json
,前一个是我实际请求后端的地址(一个restful接口),后一个是我本地的json文件。 node
在使用gulp的时候,有一个叫gulp-mock的模块,惋惜它是把mockjson转化为json的,不能实现反向代理式的转发。另外一个模块,proxy-middleware,能够实现反向代理,但就我使用来看,是目录级别的,好比配置/api/orders转发到/mock/orders.json,它会说/mock/orders.json/
不是一个目录。 git
在几番折腾各类搜索外加中途放弃的状况下,我看了下gulp-webserver(我在gulp中使用的webserver模块)的源码,发现它开放了一个middleware,经过这个middleware咱们能够拦截请求并处理(这个过程其实就是node http模块作的事情)。由于gulp-webserver的文档并无介绍这个参数的使用,因此以前我虽然知道但并无去尝试,后来阅读源码发现gulp-webserver使用的实际上是connect这个模块,而这个模块有关于middleware的使用说明。到这里,问题算是暂时性解决了。github
gulpfile.jsweb
gulp.task('webserver', function() { gulp.src('./market') .pipe(webserver({ livereload: true, directoryListing: { enable:true, path: 'market' }, port: 8000, // 这里是关键! middleware: function(req, res, next) { var urlObj = url.parse(req.url, true), method = req.method; switch (urlObj.pathname) { case '/api/orders': var data = { "status": 0, "errmsg": "", "data": [{}] }; res.setHeader('Content-Type', 'application/json'); res.end(JSON.stringify(data)); return; case '/api/goods': // ... return; case '/api/images': // ... return; default: ; } next(); } })); });
这里还只是简单的把返回的数据写在了gulpfile.js里,实际上咱们也能够把数据放在文件里,而后require进来,此外咱们也能经过method区分处理不一样请求。 ajax
这个也许不是惟一的解决办法,但此次探索给了我很多启示,这也是我在前面写那么多“废话”的缘由。做为一个成熟的开发人员,在遇到问题特别是经过搜索手段(包括询问他人、看github的issue等)仍难以获取有效信息的状况时,咱们须要深刻问题自己(好比看源码、探究实现原理),作探索问题的先驱者。编程