分割線如下是原來寫的,其實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等)仍難以獲取有效信息的狀況時,咱們須要深刻問題自己(好比看源碼、探究實現原理),作探索問題的先驅者。編程