1. 程式人生 > 實用技巧 >08【Express框架】 Express框架簡介,中介軟體, Express請求處理,express-art-template模板引擎.

08【Express框架】 Express框架簡介,中介軟體, Express請求處理,express-art-template模板引擎.

Express框架

學習內容及目標:

  1. 能夠使用Express建立web伺服器
  2. 能夠使用Express處理請求引數
  3. 能夠使用Express處理靜態資源
  4. 能夠使用中介軟體處理請求
  5. 能夠在Express中整合art-template模板引擎
  6. Express框架簡介及初體驗
  7. Express框架請求處理
  8. express-art-template模板引擎
  9. Express中介軟體

1. Express框架簡介及初體驗

1.1 Express框架是什麼?

1)Express是一個基於Node平臺的web應用開發框架,它提供了一系列的強大特性,幫助你建立各種Web網站應用。使用原生JS程式碼寫起來比較複雜,比較底層的;比如實現路由功能

,需要對請求地址進行解析,還要進行各種判斷,程式碼亂,不易閱讀;再比如,實現靜態資源訪問功能,還要使用檔案讀取模組,對檔案內容讀取,還要設計響應內容型別,但實際和網站本身的業務邏輯沒有關係;還有,接收post請求引數的程式碼,需要對請求物件新增事件,手動拼接請求引數,對請求引數的格式進行轉化,都是複雜的,並且和業務邏輯沒有關係;

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可以方便地託管靜態檔案,例如imgCSSJavaScript 檔案等。
  • app.use(express.static('public'));

現在,public 目錄下面的檔案就可以通過以下方式訪問了

4. express-art-template模板引擎

4.1 模板引擎

  1. 為了使 art-template模板引擎 能夠更好的和 Express框架配合,模板引擎官方在原art-template模板引擎的基礎上封裝了express-art-template
  2. 使用 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

}]