Node.js_3.Express

1 Express

1.1 Express概述

1.1.1 概述

Node.js原生提供的http模塊創建基於HTTP協議的Web服務器端應用,提供的API不夠簡單易用
解析請求消息麻煩;發送響應消息的方法單一;缺少Cookie和Session處理的直接API

Express是基於Node.js HTTP模板的極簡、靈活的Web應用開發框架;
豐富的HTTP快捷方法和任意排列組合的中間件能快速簡單的創建API;
Express在Node.js不對已有特性進行二次抽象,只擴展Web應用所需基本功能;
官網:http://expressjs.com/
中文網:http://www.expressjs.com.cn/

1.1.2 下載和安裝

npm init
npm install express --save

1.1.3 最簡Web服務器

Express框架可以方便的創建基於HTTP協議的Web服務器
1.基於http,將Express作爲請求處理函數(Express3.0系列創建HTTP服務器方式)

const http = require('http');
const express = require('express');
var app = express();//創建Express應用程序
http.createServer(app).listen(80);
//定義中間件和路由

2.直接將Express作爲服務器使用

const express=require('express');
var server=express();
server.listen(3000);

//增加中間變量
const express = require('express');
var app = express();//創建Express應用程序
var server = app.listen(80, ()=>{
	console.log(server.address().address, server.address().port);
});
//定義Express中間件和路由

瀏覽器向服務器端傳遞數據的方式:
1)get->req.query
2)post->req.body
3)路由傳參->req.params

1.2 路由

1.2.1 路由定義

Express路由:HTTP客戶端發來請求消息,服務器端程序根據請求方法請求URI確定響應方法
三部分組成:app.METHOD(PATH, HANDLER)
路由方法:對應於某個HTTP請求方法,get、post、put、delete;直接輸入地址欄默認使用get方法
路由路徑:定義請求的目標;
路由句柄(回調函數):請求處理函數,參數是請求對象和響應消息對象;

1.2.2 請求對象

Express處理請求消息的異步回調函數中,第一個形參是請求消息的描述對象,可以從中讀取請求消息中的數據

app.get('/', (req, res)=>{
	req.method//請求方法
	req.url//請求URL
	req.headers//請求頭部
	req.body//請求主體
	req.query//查詢字符串數據對象,僅限於獲取url中查詢字符串,所以不能在post方法裏使用
	req.params//路由參數對象
});

1.2.3 響應對象

Express處理請求消息的異步回調函數中,第二個形參用於設置向客戶端輸出的相應數據

app.get('/', (req, res)=>{
	res.status(200)//設置響應狀態碼
	res.type('json')//修改Content-Type響應頭
	res.set(header, value)//設置消息響應頭
	res.send('response body')//響應文本,只能響應一次;如果是數字認爲是狀態碼。
	res.sendFile('path/of/file')//響應文件,必須使用絕對路徑(__dirname) 
	res.json(obj)//發送JSON響應,將對象轉換成json格式
	res.redirect('path')//響應重定向
	res.end()//響應結束,結束以後纔會將響應對象發送給瀏覽器
});

1.2.4 處理GET請求

HTTP協議規定,GET請求表示客戶端請求指定資源,使用express路由方法中的get()方法處理客戶端提交的GET請求

app.get('/', (req,res)=>{req.query})//獲取查詢字符串數據
app.get('/user/:uid', (req, res)=>{req.params});

1.2.5 處理POST請求

HTTP協議規定,POST請求表示客戶端提交併保存數據到服務器,使用express路由方法中的post()方法處理客戶端提交的POST請求
不能使用req.query獲取post請求的數據,應該以事件的形式獲取表單數據,因爲post請求url只包含路徑以前的信息
將內存中數據轉爲字符串後,還需要引入querystring模塊才能轉爲obj對象,使用其中數據

   app.post('/user', (req,res)=>{
    	  req.on('data', (data)=>{
    	  	var body = querystring.parse(data.toString());
    	  });
    });

1.2.6 處理所有請求(不使用)

Express路由方法中的all()方法用於處理客戶端提交的GET、POST、PUT、DELETE等任意類型的請求消息
app.all(’/user’, (req, res)=>{req.query});

1.2.7 路由傳參

客戶端向服務器請求數據時,可使用傳統的查詢字符串方式,express允許在請求URI中包含請求參數。
在路由中設置了多個參數的話,要求瀏覽器端也要輸入同樣多的參數才能訪問該路由

//:uid?表示用uid來接收瀏覽器傳遞的數據
//req.params用來獲取路由傳遞的數據,格式爲對象
app.get('/user/:uid?/:pno?', (req, res)=>{
	req.params.uid
	req.params.pno
});

1.2.8 路由路徑

使用帶有模式字符串的路由路徑——?+*()

//匹配acd和abcd
app.get('/ab?cd', (req, res)=>{res.send(req.url); });
//匹配abcd和abbcd、abbbcd...
app.get('/ab+cd', (req, res)=>{res.send(req.url); });
//匹配abcd和abxcd、abSTHcd、ab123cd
app.get('/ab*cd', (req, res)=>{res.send(req.url); });
//匹配abe和abcde
app.get('/ab(cd)?e', (req, res)=>{res.send(req.url); });

使用正則表達式的路由路徑:

//匹配任何路徑中含有user的路徑
app.get(/user/, (req, res)=>{res.send(req.url); });
//匹配showuser、deluser等,不匹配showusers等
app.get(/.*user$/, (req, res)=>{res.send(req.url); });

1.3 路由器

1.3.1 路由器定義

大型項目中每個功能點對應一個路由,這些路由如果全部聲明在一個文件中不利於代碼開發維護以及成員間的分工協作。
將不同路由根據模塊邏輯劃分到不同的文件中,並用路由器加以管理,路由器是一個js文件
express.Router:路由器是一種可同時掛載多個路由的對象,這些路由功能相關,有相同的路由地址前綴。

const express = rquire('express');
//創建空的路由器對象
const router = express.Router();
//添加路由
router.get('/', (req, res)=>{res.send('...');});
router.get('/detail', (req, res)=>{res.send('...');});
//導出路由器
module.exports= router;

1.3.2 掛載路由器

路由器模塊編寫完成後,可以在主模塊中加載並使用

const product = require('./product');
//將路由器product掛載到/product目錄下
app.use('/product', product);//爲路由器分配掛載地址

如果多個路由器掛載在同一目錄下,以先定義的路由爲準

1.4 中間件

1.4.1 中間件定義

1.Express是一個自身功能極簡,完全由路由和中間件構成的web開發框架,意味着Express應用的實質就是在調用各種中間件。
2.中間件Middleware是一個函數,用於訪問請求對象和響應對象,也可以訪問web應用中處於請求響應流程中的其他中間件。
3.中間件功能:執行代碼;修改請求和響應對象;終結請求-響應過程;調用堆棧中下一個中間件;爲主要的業務邏輯所服務。
4.請求消息->中間件1->中間件2->…->路由句柄

1.4.2 中間件分類

分爲5個:應用級中間件、路由級中間件、內置中間件、第三方中間件、錯誤級中間件
1)應用級中間件
每一箇中間件就是一個函數,需要配合其他中間件或者路由使用;
中間件往後執行需要調用next()方法

//創建中間件——攔截瀏覽器請求,也可以做出響應
//不指定路徑則攔截所有路由的請求
//指定路徑則攔截特定路由server.use('', callback);
server.use((req, res, next)=>{
	console.log('驗證是否爲空');
	//res.send('驗證失敗');
	next();//繼續調用下一個中間件或路由
});

app.use( [path], middlewareFn );
//path參數可選,指定中間件應用到的請求路徑
//middlewareFn必需,指定執行的中間件函數

function bodyParser() {
	return function(req, res, next ) {
		req.on('data', (data)=>{
			req.body = querystring.parse(data.toString());
			next();
		});
	}
}
app.use(bodyParser());
app.post('/user', (req, res)=>{
	//從req.body中讀取數據
});

2)路由級中間件
用於在服務器中將路由器掛載到特定的URL,即路由器

const router_user = require('./user');
server.use('/user', router_user);

3)內置中間件
Express 4.x剝離大多數中間件使之成爲獨立NPM包,僅保留一個express.static中間件用於向客戶端輸出指定目錄靜態資源文件(html、css、js、圖片等);
瀏覽器請求這些靜態資源文件,會自動到指定目錄下查找。

var express = require('express');
var server = express();
server.use(express.static('要託管的目錄'));

express.static中間件可以多次調用來訪問多個靜態資源保存目錄。
如果瀏覽器訪問的文件名在多個靜態資源保存目錄下都有,則選擇最前面的express.static中間件

3)第三方中間件
www.expressjs.com.cn/resources/middleware.html
常用第三方中間件:
body-parser:請求主體數據解析中間件
cookie-parser:Cookie數據解析中間件
cookie-session:基於Cookie的Session處理中間件
compression:響應消息壓縮中間件

使用過程:
1)下載安裝中間件模塊:
npm install body-parser
2)引入並調用中間件模塊:

//方法用於將post請求數據解析爲對象
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({
//extended表示是否使用擴展的qs模塊將查詢字符串解析爲對象
extended:false //可以使用核心模塊querystring
}));

server.post('/', (req,res)=>{
	//bodyParser中間件爲req添加了body成員
	console.log(req.body);//req.body返回數據的對象格式
});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章