本文是在已經看過express官方入門指南,和用express作過一點項目經驗後,再次從新學習express的一篇私人筆記。因此一些基礎知識,本文將會一筆帶過html
已經看過express官網的小仙女小哥哥們可能會發現,按照官網教程(不論是否使用generator),撘起來的一個應用,是同時包含前端邏輯和後端邏輯的,好比能夠用.get(/)這種方式,既能夠.render(),.sendfile()等方法輸出一個html頁面在網頁上,也能夠.json()等方式返回一個json對象(如同通常的先後端項目時,前端同窗請求後端java接口,後端返回給前端的數據同樣)。前端
但在vue和webpack流行的當下,不少前端項目是用的webpack提供的編譯服務環境在跑的,最後打包壓縮成一個html一個js,發給後端同窗去部署,這樣子,再結合express用的的時候,就沒有必要再在express裏設置什麼view engine(前端模板引擎jade,ejs等)、也不用配置什麼less/sass編譯(由於webpack的loader會作的)。vue
因此本文的意思,就是隻用express作一個後端服務:接受並返回前端的get\post\put\delete等請求內容。就是一個純的服務端。順便從新學習一下各個express中間件。java
--------------------------------------------分割線-------------------------------------------------------node
*基礎環境:安裝好你的node和express。node8.9.X以上,express4(3和4有很大不一樣)jquery
*express官網: http://www.expressjs.com.cn/4x/api.html#reswebpack
*個人電腦系統:mac (部分步驟若是在windows上有不一樣或者報錯,等我之後若是用windows作開發了再說)git
1.新建項目文件夾,裏面新建一個app.js和package.json。結構以下:github
node_modules是待會用‘npm install’下載下來的 。web
--app.js--
1 /** 2 * Module dependencies. 3 */ 4 5 var express = require('express'); 6 var http = require('http'); 7 8 9 var app = express(); 10 11 // all environments 12 app.set('port', 3000); 13 14 15 http.createServer(app).listen(app.get('port'), function(){ 16 console.log('Express server listening on port ' + app.get('port')); 17 });
--package.json--
{ "name": "basicBackend", "version": "1.0.0", "private": true, "scripts": { "start": "node app" }, "dependencies": { "express": "~4.14.1" }, "devDependencies": {} }
建好這2個文件後,npm install 一下下載node_modules,一個最簡單的服務端只須要express和http這2個模塊。
而後打開終端/命令行,cd到本文件夾底下 npm run start 把項目運行起來。
出現圖中文字,表示服務啓動成功。
2.新建一個get請求。
預期效果是:html頁面裏用jquery的$.ajax去請求該get接口,能正常被響應和得到返回值,如同通常的前端請求java後端接口。
修改app.js以下(黃色表示新增):
1 /** 2 * Module dependencies. 3 */ 4 5 var express = require('express'); 6 var http = require('http'); 7 var bodyParser = require('body-parser'); 8 9 var app = express(); 10 app.set('port', 3000); 11 12 app.get('/getUserInfo', function(req, res, next){ 13 console.log('get用戶請求數據爲:'); 14 console.log(req.query); 15 16 res.json({ 17 meta:{ 18 code:200 19 }, 20 data:{ 21 message:'蛤蟆皮' 22 } 23 }); 24 }); 25 26 http.createServer(app).listen(app.get('port'), function(){ 27 console.log('Express server listening on port ' + app.get('port')); 28 });
---解釋---:
(1)、app.get()表示接收全部前端來的get請求方式,同理,app.post(),app.delete()分別表示接受前端發來的post請求與delete請求方式。
(2)、app.get(path, callback [, callback ...]):傳參,第一個參數是路徑,後面的參數都是是回調函數,能夠放1個或者多個回調函數,通常只用到1個回調,本例也只用了1個回調。官方對這個方法的解釋是:Routes HTTP GET requests to the specified path with the specified callback functions,意即‘用指定回調方法向指定路徑發送http get請求’,通俗講就是對path參數表示的接口執行一些操做,這些操做寫在第二個參數即回調函數內。
(3) app.get()中的第二個(+)參數---回調函數:該回調函數接受3個參數,按照大多數人的不成文的書寫慣例,這三個傳參寫做req, res, next。第一個參數表示http請求對象(request),第二個參數表示response對象,第三個參數是next函數,表示將控制權交給下一個中間件。next有點複雜不詳說,只要記住一個請求結束後,不要後面寫next(),常見的res.send(),res.json()都屬於請求結束,後面不要再寫next()了.
(4)res.json(obj) 表示返回一個json對象,該對象的詳細數據就是括號裏的東西啦。
----------
保存並重啓項目。
3.而後另建一個前端項目,裏面新建個html,寫個ajax請求試一下這個接口:(這個html就不要放在本express項目內了,以避免引發混淆,並且下面我要說解決跨域,若是該html文件建在本express項目內就不會出現跨域問題了)。
testRequestMyExpressBack.html
$.ajax({ url:'http://192.168.0.105:3000/getUserInfo', type:'get', data:{ id:233, name:'小明' }, success:function(p){ console.log(p); console.log(p.data); }, error: function(x,h,r){ console.log(r) } });
不出所料的話,這個html會報錯跨域。因此此處使用‘停用跨域策略的google瀏覽器或則safari瀏覽器’。而後瀏覽器控制檯裏能夠看到本次請求的結果:
express服務端返回的數據,也正如例中所寫。至此一個能正常響應前端發來的get請求的express服務端就算完成了。下文開始,繼續配置其餘參數和模塊使其能響應POST/PUT/DELETE請求、容許跨域、打印臺輸出日誌等常見功能。
app.js里加上這2句:
var express = require('express'); var http = require('http'); var app = express(); app.set('port', 3000); app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,PATCH,OPTIONS"); next(); }); app.get('/getUserInfo', function(req, res, next){ .........
--解釋--:
(1)Access-Control-Allow-Origin", "*" 表示容許來自全部源的。
(2)Access-Control-Allow-Methods","PUT,POST,GET,DELETE,PATCH,OPTIONS" 表示容許跨域的請求方式。
(3)res.header(): .header()是response對象的一個方法,用於給response頭設置鍵值。它是res.set()的別名,傳參一毛同樣
這一段要放在最上頭。
post接口的寫法與get類似,可是整個app.js中須要額外引入body-paser這個中間件來解析前端傳入的數據。
var express = require('express'); var http = require('http'); var bodyParser = require('body-parser');//引入body-parser var app = express(); // all environments app.set('port', 10303); app.use(bodyParser.json());//使用bodyparser並配置其參數 app.use(bodyParser.urlencoded({ extended: false }));//使用bodyparser並配置其參數
body-parser 官網https://www.npmjs.com/package/body-parser
官方說明爲Parse incoming request bodies in a middleware before your handlers, available under the req.body
property.
意即:在執行你本身的事件前,先解析傳入的請求體(request bodies),你能夠直接使用req.body來獲得解析後的請求體。例如:
前端js中:
//這是一個很常見的前端ajax post請求
$.ajax({ url:'http://192.168.0.105:10303/postUserInfo', type:'post', data:{ age: 85 }, success:function(p){ $("#result").html(p); console.log(p); }, error: function(x,h,r){ console.log(r) } });
如今在express項目中的app.js中新寫一個post接口:
app.post('/postUserInfo', function(req, res, next){ console.log('post用戶請求數據爲:'); console.log(req.body);//打印結果爲{age: 85},也就是前端ajax中的data字段的值 res.json({ meta:{ code:200 }, data:{ message:'啦啦啦啦啦' } }); });
寫法與post和get的一致。例如:
app.put('/putUserInfo', function(req, res, next){ console.log('put用戶傳入數據爲:'); console.log(req.body); res.json({ meta:{ code:200 }, data:{ message:'請求putUserInfo接口成功' } }); }); app.delete('/deleteUserInfo', function(req,res,next){ console.log(req.body); res.json({ meta:{ code:200, message:"success_個人deleteUserInfo接口成功" }, data:null }); });
可是須要注意跨域的問題,(若是整個項目不存在跨域,能夠pass本小節)。
只以跨域中的Preflighted Request(預檢請求)爲例:
修改app.js中關於跨域一段的設置:
app.js
app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Methods","OPTIONS,PUT,POST,GET,DELETE,PATCH"); if(req.method === 'OPTIONS'){ res.statusCode = 200; res.end(); }else{ next(); } });
l另外推薦一個第三方跨域處理的包CORS:https://github.com/expressjs/cors。可處理多種自定義配置。
至此一個基礎的能夠跨域的響應前端發送來的get/post/put/delete等請求的最簡express程序就完成了。項目地址:https://github.com/hamuPP/express-study/tree/master/basicBackend
固然,一個完整的express後端至少還須要設置cookie,session,還有常見用法.use()也並未涉及