Express 總結


Express
Express提供了一個輕量級模塊,把nodejs的http功能封裝在一個簡單易用的接口中。Express也擴展了http模塊的功能,能輕松處理服務器的路由、響應、cookie和HTTP請求的狀態。
 
一 安裝和配置
1.全局安裝
npm install -g express   
輸入express -h如果出現:

執行:npm install -g express-generator

我們可以查看express的版本,通過npm ls查看express和它的依賴的樹形結構

2.Express的配置
express對象提供了set(setting,value)、enable(setting)和disable(setting)方法來為應用程序的設置來設定值。
如啟用信任代理:app.enable('trust proxy');
一般能設置的有:
env    定義環境模式字符串,如development,testing,production,默認值是process.env.NODE_ENV
trust_proxy     啟用/禁用反向代理的支持,默認為false
jsonp callback name  定義JSONP請求的默認回調名稱。默認值是?callback=
json replacer   定義JSON replacer回調函數,默認為null
json spaces  指定當格式化JSON響應時使用的空格數量,默認在開發中為2,在生產為0
case sensitive routing   啟用/禁用區分大小寫,如/home與/Home是不一樣的,默認為disabled
strict routing   啟用/禁用嚴格的路由,如/home和/home/是不一樣的,默認為disabled
view cache  啟用/禁用視圖模板編譯緩存,默認為enabled
view engine    指定呈現模板時,如果從視圖中省略了文件擴展名,應該使用的默認模板引擎擴展
views       指定模板引擎用來查找視圖模板的路徑,默認值是./views
 
二 啟動express服務器
var express=require('express');
var app=express();
app.listen(8080);
注意,listen()方法調用底層的HTTP連接綁定到port上,並開始監聽它。事實上,express()返回的值實際上是一個回調函數,它映射了傳遞到http.createServer()和https.createServer()方法的回調函數。
用express實現HTTP和HTTPS服務器
var express=require('express');
var https=require('https');
var http=require('http');
var fs=require('fs');
var options={
    host:'127.0.0.1',
    key:fs.readFileSync('ssl/server.key'),
    cert:fs.readFileSync('ssl/server.crt')
};
http.createServer(app).listen(80);
https.createServer(options,app).listen(443);
app.get('/',function(req,res){
    res.send('Hello, Express');
});
一個典型的使用express的app.js,主要做了以下幾件事:
(1)導入相關模塊
(2)執行過var app=express()后,
使用app.set設置express內部的一些參數(options)
使用app.use來注冊函數
通過http.createServer用app來處理請求
實 際上,express通過app.use注冊middleware,middleware相當於request的handlers,在處理request 時,順序執行每一個handler(function),handler業務完成后,通過調用next(),決定是否調用下一個handler,也就是所謂的鏈式處理。

 

三 路由 
1.可以把路由定義為兩部分,第一部分是HTTP請求方法,通常是get或post。第二部分是URL中指定的路徑。
app.get(path,[middleware],callback)
app.post(path,[middleware],callback)
其中,middleware是回調函數執行前要應用的中間件函數,callback是應該處理該請求並把響應發回給客戶端的請求處理程序,callback以Request對象作為第一個參數,以Response對象作為第二個參數。
此外,Express還提供了app.all()方法,該方法與post、get一樣,唯一的區別是,app.all()用於指定路徑的每個請求,不管是任何一種方法。同時app.all()還可以接受*作為路徑的通配符,這對於實現記錄請求日志和其他特殊的功能來處理請求是一個很棒的特性,如:
app.all('*',function(req,res){
    //全部路徑的全局處理程序
});
2.在路由中應用參數
在復雜系統中,路由數量會很多,為了減少路由數量,可以在URL中實現參數。通過路由,可以為不同的請求提供唯一值來定義應用程序如何處理請求並生成響應。
實現路由參數主要有4種方法:
(1)查詢字符串,如?key=value&key=value...
var express=require('express');
var url=require('url');
var app=express();
app.get('/find',function(req,res){
    var url_parts=url.parse(req.url,true);
    var query=url_parts.query;
    res.send('Finding Book:Author: '+query.author+' Title: '+query.title);
});
如果是下面的URL:/find?author=Brad&title=Node
那么res.send()方法返回的就是:Finding Book:Author:Brad Title: Node
(2)正則表達式
app.get(/^\/book\/(\w+)\:(\w+)?$/,function(req,res){
    res.send('Get Book: Chapter: '+req.params[0]+' page: '+req.params[1]);
});
如果是下面的URL:/book/12:15
res.send()方法返回:
Get Book: Chapter: 12 page: 15
注意:這里的參數的值未被命名,req.params是與URL路徑中的條目匹配的數組。
(3)使用已定義的參數來應用路由參數
app.get('/user/:userid',function(req,res){
    res.send('Get User: '+req.param('userid'));
});
如果是下面的URL:/user/111
res.send()方法返回: Get User: 111
(4)為已定義的參數應用回調函數
app.param(param,function(req,res,next,value){})
注意,這里的next是一個用於已注冊的下一個app.param()回調的回調函數,必須要在回調函數中的某處調用next(),否則回調鏈會被破壞。value是從URL路徑解析的參數的值。
3.Request對象
Request對象是作為第一個參數傳遞到路由處理程序,它的一些常用屬性和方法:
originalUrl      請求的原始URL字符串
protocol     協議的字符串,如http或https
ip   請求的ip地址
path    請求的路徑部分
host   請求的主機名
method    HTTP方法
query     請求的URL的查詢字符串部分
fresh    一個布爾值,當最后修改與當前匹配時為true
stale   一個布爾值,當最后修改與當前匹配時為false
secure   一個布爾值,當建立TLS連接時為true
acceptsCharset(charset)   一個方法,如果由charset指定的字符集受支持,返回true
get(header)      返回header的值的方法
headers     請求標頭的對象形式
4.Response對象
傳遞到路由處理程序的Response對象提供了必要的功能來建立和發送適當的HTTP響應。
(1)設置標頭
get(header)    返回指定的header參數的值
set(header,value)    設置header參數的值
set(headerObj)    接受一個對象,包括多個'header':'value'屬性
locatio(path)    把location標頭設置為指定的path參數
type(type_string)    根據type_string參數設置Content-Type標頭
attachment([filepath])    把Content-Disposition標頭設置為attachment,並且如果指定filepath,則Content-Type頭是基於文件擴展名設置的
(2)設置狀態
res.status(200);   //正確
300    Rediction重定向
400     Bad Request錯誤的請求
401  Unauthorized未經許可
403   Forbidden禁止
500  Server Error服務器錯誤
(3)發送響應
res.send(status,[body])
body是一個String或者Buffer對象,如果指定Buffer對象,內容類型就被自動設置為application/octet-stream(應用程序/八位字節流)
(4)發送JSON響應
res.json(status,[object])
如:
app.get('/json',function(req,res){
    app.set('json spaces',4);
    res.json({name:'bob',built:'1223',centers:['art','maths']});
});
app.get('jsonp',function(res,req){
    app.set('jsonp callback name','cb');
    res.jsonp({name:'bob',built:'1223',centers:['art','maths']});
});
注意,jsonp callback name被設置為cb,意味着客戶端需要在URL中傳遞的不是?callback=<function>,而是?cb=<function>
(5)發送文件
res.sendFile(path,[options],[callback])
其中,path指向你要發送給客戶端的文件,options參數是一個對象,包含了一個maxAge屬性定義的最長期限和root屬性(用來支持path參數相對路徑的根路徑)。當文件傳輸完成時,回調函數被調用,並接受一個錯誤作為唯一的參數。
如:
app.get('/image',function(req,res){
    res.sendFile('arch.jpg',{maxAge:1,   //24*60*60*1000
                                                root:'./views'},
            function(err){
                if(err){
                    console.log('Error');
                }else{
                    console.log('Success');
                }
            });
});
(6)發送下載響應:
res.download(path,[filename],[callback])
(7)重定向響應:
res.redirect(path);
如:
app.get('/google',function(req,res){
    res.redirect('http://google.com');
});
看路由的一些例子
(1)簡單的get請求
app.js
var express = require('express');
var app = express();
var index = require('./routes/index');
var users = require('./routes/users');
app.use('/', index);
app.use('/users', users);
index.js
var express = require('express');
var router = express.Router();
 
/* GET home page. */
router.get('/', function(req, res, next) {
  res.send('hello,index');
});
module.exports = router;
user.js
var express = require('express');
var router = express.Router();
/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});
module.exports = router;
項目結構如圖:

運行結果:

 

(2)看一個正則匹配的例子
在index.js添加:
router.get('/ab*cd',function(req,res){
  console.log('/ab*cd GET請求');
  res.send('正則匹配');
});

(3)通過表單提交的post請求
新建index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<form method="post" action="http://localhost:3000/">
    <input type="submit" value="訪問" />
</form>
</body>
</html>

點擊訪問后出現:

 

三 實現模板引擎
1.一個日益增長的趨勢是,使用模板文件和應用程序數據,借助模板引擎來生成HTML,而不是從頭開始構建HTML文件。Express中兩個重要的模板,Jade和內嵌的javascript(EJS)。
Jade使用HTML的速記符號模板,模板文件非常小,但是需要掌握另一種語言;EJS使用特殊的符號在正常的HTML文檔中嵌入javascript,使得它更容易從正常的HTML過度,但是該HTML會比原始文檔復雜的多,不如Jade模板簡潔。
2.安裝jade和ejs:
npm install jade --save
npm install ejs --save
安裝后可以到package.json中查看
3.定義引擎模板
var app=express();
app.set('views','./views');     //也可以寫成app.set('views',path.join(_dirname,'views'));即根目錄下的views文件夾下
app.set('view engine','jade');
看一個例子:
app.js:
var express = require('express');
var app = express();
var path = require('path');
//指明模板目錄:./views
app.set('views', path.join(__dirname, 'views'));
//使用ejs引擎
app.set('view engine', 'ejs');
node中的path.join方法:將多個參數組合成一個path
path.join([path1],[path2],...);
注意:該方法屬於path模塊,使用前需要引入path模塊
 
index.js
var express = require('express');
var router = express.Router();
//尋找views/index,提交ejs渲染,並返回結果
router.get('/', function(req, res, next) {
  res.render('index',{title:'express'});
});
module.exports = router;
 
使用ejs模板,index.ejs
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
  </body>
</html>

4.引入靜態文件
在app.js中添加:
app.use(express.static(path.join(__dirname, 'public')));
查看一下目錄文件,這里我們要引用的是public/stylesheets/style.css

index.ejs
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h1><%= title %></h1>
    <p>Welcome to <%= title %></p>
  </body>
</html>
style.css:
body {
  padding: 50px;
  font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
  color: #00B7FF;
}

 

四 Express中間件
1.Express提供的大部分功能是通過中間件函數完成的,這些中間件函數在nodejs收到請求的時點和發送響應的時點之間執行。Express的connect模塊提供了中間件框架,讓你方便的在全局或路徑級別或為單個路由插入中間件功能。通過Express支持的中間件可以讓你快速提供靜態文件,實現cookie,支持會話,處理post數據等等,你甚至可以創建自己的自定義中間件函數,並利用它們來預處理請求和提供自己的功能。
2.有哪些中間件
Express建立在connect NPM模塊之上,提供了connect所提供的底層中間件支持。以下是Express支持的中間件:
static   允許Express服務器以流式處理靜態文件的GET請求,這個中間件是Express內置的,它可以通過express.static()訪問
express-logger   實現一個格式化的請求記錄器來在跟蹤對服務器的請求
basic-auth-connect    提供對基本的HTTP身份驗證的支持
cookie-parser   可以從請求讀取cookie並在響應中設置cookie
cookie-session   提供基於cookie的會話支持
express-session   提供了一個強大的會話支持
body-parser   把POST請求正文中的JSON數據解析為req.body屬性
compression  對發給客戶端的大響應提供Gzip壓縮支持
caurf     提供跨站點請求偽造保護
3.安裝:
npm install body-parser --save
也可以把express添加到package.json模塊,以確保當你部署應用程序時,這些模塊被安裝。
4.分配中間件
(1)在全局范圍內把中間件分配給某個路徑
要對所有路由指定中間件,可以在Express app對象上實現Use()方法:
use([path],middleware)
其中,path是可選的,默認為/,意味着所有的路徑,middleware是一個函數,即function(req,res,next){},每個中間件函數都有一個構造函數,它返回相應的中間件功能。next是要執行的下一個中間件函數。
例如,把body-parser中間件應用於所有路徑:
var express=require('express');
var bodyParser=require('body-parser');
var app=express();
app.use('/',bodyParser());
(2)把中間件分配到單個路由
var express=require('express');
var bodyParser=require('body-parser');
var app=express();
app.get('/parseRoute',bodyParser(),function(req,res){
        //function
});
(3)添加多個中間件函數
可以根據需要在全局范圍和路由上分配任意多的中間件函數。如:
var express=require('express');
var bodyParser=require('body-parser');
var cookieParser=require)('cookie-parser');
var session=require('express-session');
var app=express();
app.use('/',bodyParser()).use('/',cookieParser()).use('/',session());
注意,你分配函數的順序就是它們在請求中被應用的順序。一些中間件需要被添加在別的中間件函數前面。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM