08【Express框架】 Express框架簡介,中介軟體, Express請求處理,express-art-template模板引擎.
Express框架
學習內容及目標:
- 能夠使用Express建立web伺服器
- 能夠使用Express處理請求引數
- 能夠使用Express處理靜態資源
- 能夠使用中介軟體處理請求
- 能夠在Express中整合art-template模板引擎
- Express框架簡介及初體驗
- Express框架請求處理
- express-art-template模板引擎
- Express中介軟體
1. Express框架簡介及初體驗
1.1 Express框架是什麼?
1)Express是一個基於Node平臺的web應用開發框架,它提供了一系列的強大特性,幫助你建立各種Web網站應用。使用原生JS程式碼寫起來比較複雜,比較底層的;比如實現路由功能
2)這個是nodejs的第三方模組-使用 npm install express 命令進行下載。企業中建立web應用的標準
1.2 Express框架特性
- 提供了方便簡潔的路由定義方式:router第三方模組 ,其實就是從express框架中抽取出來的
- 對獲取HTTP請求引數進行了簡化處理
- 對模板引擎 支援程度高,方便渲染動態HTML頁面
- 提供了中介軟體(對請求的攔截)機制有效控制HTTP請求
- 擁有大量第三方中介軟體 對功能進行擴充套件:非常少的程式碼,做同樣的事情
1.3 原生Node.js與Express框架對比 之 路由
app.on('request', (req, res) => { // 獲取客戶端的請求路徑 let { pathname } = url.parse(req.url); // 對請求路徑進行判斷 不同的路徑地址響應不同的內容 if (pathname == '/' || pathname == 'index') { res.end( } else if (pathname == '/list') { res.end('歡迎來到列表頁'); } else if (pathname == '/about') { res.end('歡迎來到關於我們頁面') } else { res.end('抱歉, 您訪問的頁面出遊了'); } }); |
// 當客戶端以get方式訪問/時 app.get('/', (req, res) => { // 對客戶端做出響應 res.send('Hello Express'); }); // 當客戶端以post方式訪問/add路由時 app.post('/add', (req, res) => { res.send('使用post方式請求了/add路由'); }); |
1.4 原生Node.js與Express框架對比 之 獲取請求引數
app.on('request', (req, res) => { // 獲取GET引數 let {query} = url.parse(req.url, true); // 獲取POST引數 let postData = ''; req.on('data', (chunk) => { postData += chunk; }); req.on('end', () => { console.log(querystring.parse(postData) })); }); |
app.get('/', (req, res) => { // 獲取GET引數 console.log(req.query); }); app.post('/', (req, res) => { // 獲取POST引數 console.log(req.body); }) |
1.5 Express初體驗
使用Express框架 建立web伺服器及其簡單,呼叫express模組 返回的函式即可。
// 引入Express框架 const express = require('express'); // 使用框架建立web伺服器 const app = express(); // 當客戶端以get方式訪問/路由時 app.get('/', (req, res) => { // 對客戶端做出響應 send方法會根據內容的型別自動設定請求頭 res.send('Hello Express'); // <h2>Hello Express</h2> {say: 'hello'} }); // 程式監聽3000埠 app.listen(3000); |
2. 中介軟體
2.1 什麼是中介軟體
1) 中介軟體就是 一堆方法,可以 接收客戶端發來的請求、可以對請求做出響應,也可以將請求繼續交給下一個中介軟體繼續處理。
2) 中介軟體主要由兩部分構成,中介軟體方法以及請求處理函式。 中介軟體方法 由Express提供,負責攔截請求,請求處理函式 由開發人員提供,負責處理請求。
app.get('請求路徑', '處理函式') // 接收並處理get請求 app.post('請求路徑', '處理函式') // 接收並處理post請求 |
3) 可以針對同一個請求設定 多箇中間件,對同一個請求進行多次處理。
預設情況下,請求從上到下依次匹配中介軟體,一旦匹配成功,終止匹配。 可以呼叫next()方法將請求的控制權交給下一個中介軟體,直到遇到結束請求的中介軟體
app.get('/request', (req, res, next) => { req.name = "zhangsan"; next(); }); | app.get('/request', (req, res) => { res.send(req.name); }); |
2.2 app.use中介軟體用法
- app.use 匹配所有的請求方式,可以直接傳入請求處理函式,代表接收所有的請求
app.use((req, res, next) => { console.log(req.url); next(); });
中介軟體是有順序的
- app.use 第一個引數 也可以傳入請求地址,代表不論什麼請求方式,只要是這個請求地址就接收這個請求。
app.use('/admin', (req, res, next) => { console.log(req.url); next(); });
2.3 中介軟體應用
1). 路由保護
客戶端在訪問 需要登入的頁面時,可以先使用中介軟體判斷使用者登入狀態,使用者如果未登入,則攔截請求,直接響應, 禁止使用者進入需要登入的頁面。
2). 網站維護公告
在所有路由的最上面定義接收所有請求的中介軟體,直接為客戶端做出響應,網站正在維護中。
3). 自定義404頁面
2.4 錯誤處理中介軟體
- 在程式執行的過程中,不可避免的會出現一些無法預料的錯誤,比如檔案讀取失敗,資料庫連線失敗,錯誤處理中介軟體是一個集中處理錯誤的地方。
- 想要出錯以後,還能繼續執行,需要捕獲錯誤,處理
- 只能捕獲到同步程式碼錯誤,非同步需要手動觸發,呼叫next(0方法 當非同步程式出現錯誤時,呼叫next()方法,並且將錯誤資訊通過引數的形式傳遞給next()方法,即可觸發錯誤處理中介軟體
app.use((err, req, res, next) => { res.status(500).send('伺服器發生未知錯誤'); }) |
app.get("/", (req, res, next) => { fs.readFile("/file-does-not-exist", (err, data) => { if (err) { next(err); } }); }); |
2.5 捕獲錯誤
在node.js中,非同步API的錯誤資訊 都是通過回撥函式獲取的,支援Promise物件的非同步API 發生錯誤可以通過catch方法捕獲。 非同步函式執行如果發生錯誤要如何捕獲錯誤呢?
try catch 可以捕獲非同步函式以及其他同步程式碼在執行過程中發生的錯誤,但是不能捕獲其他型別的API發生的錯誤
app.get("/", async (req, res, next) => { try { await User.find({name: '張三'}) }catch(ex) { next(ex); // 呼叫next() 觸發錯誤處理中介軟體 } }); |
3. Express請求處理
3.1 構建模組化路由
在一般情況下,路由的數量是非常多的,如果將所有的放在同一檔案中,非常可怕?所以提供了模組化,進行分類,方便管理。
例如:部落格網站:使用者看的,文章列表,詳情頁面。管理員看的文章釋出等。
const express = require('express') // 建立路由物件 const home = express.Router(); // 將路由和請求路徑進行匹配 app.use('/home', home); // 在home路由下繼續建立路由,/home/index 二級路由 home.get('/index', () => { // /home/index res.send('歡迎來到部落格展示頁面'); }); |
3.2 構建模組化路由
// home.js
| // admin,js
|
// app.js |
3.3 GET引數的獲取
Express框架中使用 req.query 即可獲取 GET引數,框架內部會將GET引數 轉換為 物件並返回。
// 接收位址列中問號後面的引數 // 例如: http://localhost:3000/?name=zhangsan&age=30 app.get('/', (req, res) => { console.log(req.query); // {"name": "zhangsan", "age": "30"} }); |
3.4 POST引數的獲取
Express中接收 post請求引數 需要藉助第三方包 body-parser。
// 引入body-parser模組 const bodyParser = require('body-parser'); // 配置body-parser模組 app.use(bodyParser.urlencoded({ extended: false })); // 接收請求 app.post('/add', (req, res) => { // 接收請求引數 console.log(req.body); }) |
html檔案
3.5 Express路由引數
更容易看出傳了那些引數
app.get('/find/:id', (req, res) => { console.log(req.params); // {id: 123} req.params 獲取引數 }); localhost:3000/find/123 |
3.6 靜態資源的處理
- 通過Express內建的 express.static可以方便地託管靜態檔案,例如img、CSS、JavaScript 檔案等。
- app.use(express.static('public'));
現在,public 目錄下面的檔案就可以通過以下方式訪問了。
- http://localhost:3000/images/kitten.jpg
- http://localhost:3000/css/style.css
- http://localhost:3000/js/app.js
- http://localhost:3000/images/bg.png
- http://localhost:3000/hello.html
4. express-art-template模板引擎
4.1 模板引擎
- 為了使 art-template模板引擎 能夠更好的和 Express框架配合,模板引擎官方在原art-template模板引擎的基礎上封裝了express-art-template。
- 使用 npm install art-template express-art-template 命令進行安裝。
// 當渲染字尾為art的模板時 使用express-art-template app.engine('art', require('express-art-template')); // 設定模板存放目錄 app.set('views', path.join(__dirname, 'views')); // 渲染模板時不寫字尾 預設拼接art字尾 app.set('view engine', 'art'); app.get('/', (req, res) => { // 渲染模板 res.render('index'); }); |
4.2 app.locals 物件
不同的頁面中,總會有公共資料,程式碼中如何查詢公共資料呢?
- 在不同頁面路由中 都去查詢這個相同的資料,render將資料填充到模板中,麻煩; 只寫一次,讓所有能用到都而已來拿到這個數據呢?
- 將變數設定到 app.locals物件下面,這個資料在所有的模板中都可以獲取到。
app.locals.users = [{ name: '張三', age: 20 },{ name: '李四', age: 20 }] |