Express框架是後臺的Node框架,因此和jQuery、zepto、yui、bootstrap都不一個東西。html
Express在後臺的受歡迎的程度,和jQuery同樣,就是企業的事實上的標準。正則表達式
● 原生Node開發,會發現有不少問題。好比:數據庫
■ 呈遞靜態頁面很不方便,須要處理每一個HTTP請求,還要考慮304問題express
■ 路由處理代碼不直觀清晰,須要寫不少正則表達式和字符串函數npm
■ 不能集中精力寫業務,要考慮不少其餘的東西json
咱們本身能夠把第一天的做業,就是那個靜態文件服務給封裝成爲模塊。封裝的越多,就本身作出了相似Express的東西。bootstrap
● EXPRESS的哲學是在你的想法和服務器之間充當薄薄的一層。這並不意味着他不夠健壯,或者沒有足夠的有用特性,而是儘可能少干預你,讓你充分表達本身的思想,同時提供一些有用的東西。數組
英語官網:http://expressjs.com/服務器
中文官網:http://www.expressjs.com.cn/app
總體感知,Express框架。
安裝Express框架,就是使用npm的命令。
1 npm install --save express |
--save參數,表示自動修改package.json文件,自動添加依賴項。
路由能力:
1 var express = require("express"); 2 3 var app = express(); 4 5 app.get("/",function(req,res){ 6 res.send("你好"); 7 }); 8 9 app.get("/haha",function(req,res){ 10 res.send("這是haha頁面,哈哈哈哈哈哈"); 11 }); 12 13 app.get(/^\/student\/([\d]{10})$/,function(req,res){ 14 res.send("學生信息,學號" + req.params[0]); 15 }); 16 17 app.get("/teacher/:gonghao",function(req,res){ 18 res.send("老師信息,工號" + req.params.gonghao); 19 }); 20 21 app.listen(3000); |
靜態文件伺服能力:
1 app.use(express.static("./public")); |
模板引擎:
1 var express = require("express"); 2 3 var app = express(); 4 5 app.set("view engine","ejs"); 6 7 app.get("/",function(req,res){ 8 res.render("haha",{ 9 "news" : ["我是小新聞啊","我也是啊","哈哈哈哈"] 10 }); 11 }); 12 13 app.listen(3000); |
咱們學習的是Express4.X,和Express3.X差異很是大。
當用get請求訪問一個網址的時候,作什麼事情:
1 app.get("網址",function(req,res){ 2 3 }); |
當用post訪問一個網址的時候,作什麼事情:
1 app.post("網址",function(req,res){ 2 3 }); |
若是想處理這個網址的任何method的請求,那麼寫all
1 app.all("/",function(){ 2 3 }); |
這裏的網址,不分大小寫,也就是說,你路由是
1 app.get("/AAb",function(req,res){ 2 res.send("你好"); 3 }); |
實際上小寫的訪問也行。
全部的GET參數,? 後面的都已經被忽略。 錨點#也被忽略
你路由到/a , 實際/a?id=2&sex=nan 也能被處理。
正則表達式能夠被使用。正則表達式中,未知部分用圓括號分組,而後能夠用req.params[0]、[1]獲得。
req.params類數組對象。
1 app.get(/^\/student\/([\d]{10})$/,function(req,res){ 2 res.send("學生信息,學號" + req.params[0]); 3 }); |
冒號是更推薦的寫法。
1 app.get("/student/:id",function(req,res){ 2 var id = req.params["id"]; 3 var reg= /^[\d]{6}$/; //正則驗證 4 if(reg.test(id)){ 5 res.send(id); 6 }else{ 7 res.send("請檢查格式"); 8 } 9 }); |
表單能夠本身提交到本身上。
1 app.get("/",function(req,res){ 2 res.render("form"); 3 }); 4 5 app.post("/",function(req,res){ 6 //將數據添加進入數據庫 7 res.send("成功"); 8 }); |
適合進行 RESTful路由設計。簡單說,就是一個路徑,可是http method不一樣,對這個頁面的使用也不一樣。
/student/345345
get 讀取學生信息
add 添加學生信息
delete 刪除學生新
若是個人的get、post回調函數中,沒有next參數,那麼就匹配上第一個路由,就不會往下匹配了。
若是想往下匹配的話,那麼須要寫next()
1 app.get("/",function(req,res,next){ 2 console.log("1"); 3 next(); 4 }); 5 6 app.get("/",function(req,res){ 7 console.log("2"); 8 }); |
下面兩個路由,感受沒有關係:
1 app.get("/:username/:id",function(req,res){ 2 console.log("1"); 3 res.send("用戶信息" + req.params.username); 4 }); 5 6 app.get("/admin/login",function(req,res){ 7 console.log("2"); 8 res.send("管理員登陸"); 9 }); |
可是實際上衝突了,由於admin能夠當作用戶名 login能夠當作id。
解決方法1:交換位置。 也就是說,express中全部的路由(中間件)的順序相當重要。
匹配上第一個,就不會往下匹配了。 具體的往上寫,抽象的往下寫。
1 app.get("/admin/login",function(req,res){ 2 console.log("2"); 3 res.send("管理員登陸"); 4 }); 5 6 app.get("/:username/:id",function(req,res){ 7 console.log("1"); 8 res.send("用戶信息" + req.params.username); 9 }); |
解決方法2:
1 app.get("/:username/:id",function(req,res,next){ 2 var username = req.params.username; 3 //檢索數據庫,若是username不存在,那麼next() 4 if(檢索數據庫){ 5 console.log("1"); 6 res.send("用戶信息"); 7 }else{ 8 next(); 9 } 10 }); 11 12 app.get("/admin/login",function(req,res){ 13 console.log("2"); 14 res.send("管理員登陸"); 15 }); |
路由get、post這些東西,就是中間件,中間件講究順序,匹配上第一個以後,就不會日後匹配了。next函數纔可以繼續日後匹配。
app.use()也是一箇中間件。與get、post不一樣的是,他的網址不是精確匹配的。而是可以有小文件夾拓展的。
好比網址: http://127.0.0.1:3000/admin/aa/bb/cc/dd
1 app.use("/admin",function(req,res){ 2 res.write(req.originalUrl + "\n"); // /admin/aa/bb/cc/dd 3 res.write(req.baseUrl + "\n"); // /admin 4 res.write(req.path + "\n"); // /aa/bb/cc/dd 5 res.end("你好"); 6 }); |
若是寫一個/
1 //當你不寫路徑的時候,實際上就至關於"/",就是全部網址 2 app.use(function(req,res,next){ 3 console.log(new Date()); 4 next(); 5 }); |
app.use()就給了咱們增長一些特定功能的便利場所。
實際上app.use()的東西,基本上都從第三方能獲得。
● 大多數狀況下,渲染內容用res.render(),將會根據views中的模板文件進行渲染。若是不想使用views文件夾,想本身設置文件夾名字,那麼app.set("views","aaaa");
● 若是想寫一個快速測試頁,固然可使用res.send()。這個函數將根據內容,自動幫咱們設置了Content-Type頭部和200狀態碼。send()只能用一次,和end同樣。和end不同在哪裏?可以自動設置MIME類型。
● 若是想使用不一樣的狀態碼,能夠:
res.status(404).send('Sorry, we cannot find that!');
● 若是想使用不一樣的Content-Type,能夠:
res.set('Content-Type', 'text/html');
● GET請求的參數在URL中,在原生Node中,須要使用url模塊來識別參數字符串。在Express中,不須要使用url模塊了。能夠直接使用req.query對象。
● POST請求在express中不能直接得到,必須使用body-parser模塊。使用後,將能夠用req.body獲得參數。可是若是表單中含有文件上傳,那麼仍是須要使用formidable模塊。
Node中全是回調函數,因此咱們本身封裝的函數,裏面若是有異步的方法,好比I/O,那麼就要用回調函數的方法封裝。
錯誤:
1 res.render("index",{ 2 "name" : student.getDetailById(234234).name 3 }); 4 5 |
正確:
6 7 student.getDetailByXueHao(234234,function(detail){ 8 res.render("index",{ 9 "name" : detail.name 10 }) 11 }); |