Node.js之Express詳解

WikY1020發表於2020-11-11

Express

Express 是基於 Node.js 平臺,快速、開放、極簡的 Web 開發框架

使用 Express,我們可以方便、快速的建立 Web 網站的伺服器或 API 介面的伺服器。

express的基本使用

安裝

npm install express

npm i express@最新版本號

建立基本的web伺服器

  1. 匯入express模組
  2. 建立web伺服器
  3. 呼叫app.listen()函式啟動伺服器
//1.匯入express模組
const express = require('express');
//2.建立web伺服器
const app = express();
//3.呼叫app.listen()函式啟動伺服器
app.listen(80, () => {
    console.log('running at http://127.0.0.1');
})

監聽GET和POST請求

app.get('請求url', (req, res) => {
});
app.post('請求url', (req, res) => {
});

獲取url中攜帶的引數

通過req.query物件可以訪問到客戶端查詢字串的形式傳送到伺服器的引數

預設時一個空物件

 app.get('/user', (req, res) => {
     console.log(req.query);
     res.send(req.query);
 });

獲取url中的動態引數

通過req.params物件可以訪問url中通過匹配到的動態引數

 app.get('/:ids/:username', (req, res) => {
    console.log(req.params);
    res.send(req.params)
 });

req.body

在伺服器,可以使用 req.body 這個屬性,來接收客戶端傳送過來的請求體資料

預設情況下,如果不配置解析表單資料的中介軟體,則 req.body 預設等於 undefined

// 匯入 express 模組
const express = require('express')
// 建立 express 的伺服器例項
const app = express()

// 注意:除了錯誤級別的中介軟體,其他的中介軟體,必須在路由之前進行配置
// 通過 express.json() 這個中介軟體,解析表單中的 JSON 格式的資料
app.use(express.json())
// 通過 express.urlencoded() 這個中介軟體,來解析 表單中的 url-encoded 格式的資料
app.use(express.urlencoded({ extended: false }))

app.post('/user', (req, res) => {
  // 在伺服器,可以使用 req.body 這個屬性,來接收客戶端傳送過來的請求體資料
  // 預設情況下,如果不配置解析表單資料的中介軟體,則 req.body 預設等於 undefined
  console.log(req.body)
  res.send('ok')
})

app.post('/book', (req, res) => {
  // 在伺服器端,可以通過 req,body 來獲取 JSON 格式的表單資料和 url-encoded 格式的資料
  console.log(req.body)
  res.send('ok')
})

// 呼叫 app.listen 方法,指定埠號並啟動web伺服器
app.listen(80, function () {
  console.log('Express server running at http://127.0.0.1')
})

路由

  1. Express 中,路由指的是客戶端的請求伺服器處理函式之間的對映關係
  2. Express 中的路由分 3 部分組成,分別是請求的型別請求的 URL 地址處理函式

模組化路由

  1. 建立路由對應的js檔案 //router.js test.js
  2. 呼叫express.Router()函式建立路由物件
  3. 向路由物件上掛載具體的路由
  4. 使用module.exports向外共享路由物件
  5. 使用app.use()函式註冊路由模組
router.js //1.建立路由對應的js檔案 router.js
const express = require('express');
//2.呼叫express.Router()函式建立路由物件
const router = express.Router();
//3.向路由物件上掛載具體的路由
router.get('/user/get', (req, res) => {
    res.send('GET success');
})
router.post('/user/post', (req, res) => {
    res.send('POST success');

});
//4.使用module.exports向外共享路由物件
module.exports = router;

test.js  //1.建立路由對應的js檔案  test.js
const express = require('express');
const app = express();

//5.引入路由模組並使用app.use()函式註冊路由模組
const router = require('./router');
app.use('/api', router);

app.listen(80, () => {
    console.log('server running at http://127.0.0.1');
})

中介軟體

​ Express 的中介軟體,本質上就是一個 function 處理函式

function (req,res,next){
    next();
}

注意:中介軟體函式的形參列表中,必須包含 next 引數。而路由處理函式中只包含 reqres

next 函式是實現多箇中介軟體連續呼叫的關鍵,它表示把流轉關係轉交給下一個中介軟體路由

定義中介軟體

const nw=(req,res,next)=>{
    next();
}

全域性生效的中介軟體

客戶端發起的任何請求,到達伺服器後都會先觸發中介軟體

通過app.use(中介軟體函式)定義一個全域性生效的中介軟體

//單個全域性生效的中介軟體
const nw=(req,res,next)=>{
    next();
}
app.use(nw);

//簡化形式
app.use((req,res,next)=>{
    next();
});

//多個全域性生效的中介軟體
app.use((req,res,next)=>{
    console.log('第一個中介軟體')
    next();
});
app.use((req,res,next)=>{
     console.log('第二個中介軟體')
    next();
});

//會按照定義中介軟體的順序來執行

中介軟體的作用

多箇中介軟體之間,共享同一份 reqres,基於這樣的特性,我們可以在上游 的中介軟體中,統一為 reqres 物件新增自定義的屬性和方法,供下游的中介軟體或路由進行使用。

const express = require('express')
const app = express()

// 這是定義全域性中介軟體的簡化形式
app.use((req, res, next) => {
    // 獲取到請求到達伺服器的時間
    // const time = Date.now()
    var time = new Date();
    // 為 req 物件,掛載自定義屬性,從而把時間共享給後面的所有路由
    req.startTime = time
    next()
})

app.get('/', (req, res) => {
    res.send('Home page.' + req.startTime)
})
app.get('/user', (req, res) => {
    res.send('User page.' + req.startTime)
})

app.listen(80, () => {
    console.log('http://127.0.0.1')
})

區域性生效的中介軟體

不適應app.use()定義的中介軟體

//單個區域性中介軟體
const nw=(req,res,next)=>{
    next();
}

app.get('/',nw,(req,res)=>{
    
})

//多個區域性中介軟體
const nw=(req,res,next)=>{
    next();
}
const nw1=(req,res,next)=>{
    next();
}

app.get('/',[nw,nw1],(req,res)=>{
    
})

使用中介軟體的注意事項

  1. 一定要在路由之前註冊中介軟體
  2. 客戶端傳送過來的請求,可以連續呼叫多箇中介軟體進行處理
  3. 執行完中介軟體的業務程式碼之後,不要忘記呼叫 next() 函式
  4. 為了防止程式碼邏輯混亂,呼叫 next() 函式後不要再寫額外的程式碼
  5. 連續呼叫多箇中介軟體時,多箇中介軟體之間,共享 reqres 物件

中介軟體的分類

應用級別的中介軟體

通過 app.use()app.get()app.post()繫結到 app 例項上的中介軟體,叫做應用級別的中介軟體

app.get('/api', (req, res) => {
    res.send('get 請求成功');
})

app.post('/api', (req, res) => {
    res.send('post 成功')
})

路由級別的中介軟體

  1. 繫結到 express.Router() 例項上的中介軟體,叫做路由級別的中介軟體
  2. 用法上和應用級別中介軟體沒有任何區別,只不過,應用級別中介軟體是繫結到 app 例項上,路由級別中介軟體繫結到 router 例項上
const express = require('express');
const app = express();
const router = express.Router();
console.log(typeof router);
router.use((req,res,next)=>{
    next();
});
app.use('/api', router);

app.listen(80, () => {
    console.log('http://127.0.0.1');
})

錯誤級別的中介軟體

  1. 錯誤級別中介軟體的作用: 專門用來捕獲整個專案中發生的異常錯誤,從而防止專案異常崩潰的問題
  2. 格式:錯誤級別中介軟體的 function 處理函式中,必須有 4 個形參,形參順序從前到後,分別是(err, req, res, next)
  3. 注意: 錯誤級別的中介軟體,必須註冊在所有路由之後
// 匯入 express 模組
const express = require('express')
// 建立 express 的伺服器例項
const app = express()

// 1. 定義路由
app.get('/', (req, res) => {
  // 1.1 人為的製造錯誤
  throw new Error('伺服器內部發生了錯誤!')
  res.send('Home page.')
})

// 2. 定義錯誤級別的中介軟體,捕獲整個專案的異常錯誤,從而防止程式的崩潰
app.use((err, req, res, next) => {
  console.log('發生了錯誤!' + err.message)
  res.send('Error:' + err.message)
})

// 呼叫 app.listen 方法,指定埠號並啟動web伺服器
app.listen(80, function () {
  console.log('Express server running at http://127.0.0.1')
});

內建級別的中介軟體

Express 4.16.0 版本開始,Express 內建了 3 個常用的中介軟體,極大的提高了 Express 專案的開發效率和體驗

  1. express.static 快速託管靜態資源的內建中介軟體,例如: HTML 檔案、圖片、CSS 樣式等(無相容性)
  2. express.json 解析 JSON 格式的請求體資料(有相容性,僅在 4.16.0+ 版本中可用)
  3. express.urlencoded 解析 URL-encoded 格式的請求體資料(有相容性,僅在 4.16.0+ 版本中可用)
const express = require('express');
const app = express();
//express.json() 中介軟體,解析表單中的 JSON 格式的資料
app.use(express.json());
//express.urlencoded 解析 URL-encoded 格式的請求體資料
app.use(express.urlencoded({ extended: false }));
app.post('/api', (req, res) => {
    console.log(req.body);
    res.send('post 成功')
})
app.listen(80, () => {
    console.log('running at http://127.0.0.1');
})

第三方的中介軟體

  1. Express 官方內建,而是由第三方開發出來的中介軟體,叫做第三方中介軟體。在專案中,大家可以按需下載並配置第三方中介軟體,從而提高專案的開發效率
  2. 例如:在 express@4.16.0 之前的版本中,經常使用 body-parser 這個第三方中介軟體,來解析請求體資料。使用步驟如下
    • 執行 npm install body-parser 安裝中介軟體
    • 使用 require 匯入中介軟體
    • 呼叫 app.use() 註冊並使用中介軟體
// 匯入 express 模組
const express = require('express')
// 建立 express 的伺服器例項
const app = express()

// 1. 匯入解析表單資料的中介軟體 body-parser
const parser = require('body-parser')
// 2. 使用 app.use() 註冊中介軟體
app.use(parser.urlencoded({ extended: false }))
// app.use(express.urlencoded({ extended: false }))

app.post('/user', (req, res) => {
  // 如果沒有配置任何解析表單資料的中介軟體,則 req.body 預設等於 undefined
  console.log(req.body)
  res.send('ok')
})

// 呼叫 app.listen 方法,指定埠號並啟動web伺服器
app.listen(80, function () {
  console.log('Express server running at http://127.0.0.1')
})

注意:Express 內建的 express.urlencoded 中介軟體,就是基於 body-parser 這個第三方中介軟體進一步封裝出來的

使用express寫介面

1.建立web伺服器

// 匯入 express 模組
const express = require('express')
// 建立 express 的伺服器例項
const app = express();

//設定解析資料的
app.use(express.urlencoded({ extended: false }));

// 匯入路由模組
const router = require('./16.apiRouter')
// 把路由模組,註冊到 app 上
app.use('/api', router)


// 呼叫 app.listen 方法,指定埠號並啟動web伺服器
app.listen(80, function () {
  console.log('Express server running at http://127.0.0.1')
})

2.建立API路由模組

const express = require('express')
const router = express.Router();

//get請求
router.get('/get', (req, res) => {
    var query = req.query;
    res.send({
        status: 0,
        msg: "GET 請求成功",
        data: query

    });
});
//post請求
router.post('/post', (req, res) => {
    var body = req.body;

    res.send({
        status: 0,
        msg: "POST請求成功",
        data: body
    })
})

module.exports = router

cors

  1. CORS (跨域資源共享) 由一系列 HTTP 響應頭組成,這些 HTTP 響應頭決定瀏覽器 是否阻止前端 JS 程式碼跨域獲取資源
  2. 瀏覽器的同源安全策略預設會阻止網頁“跨域”獲取資源。但如果介面伺服器配置了 CORS 相關的 HTTP 響應頭,就可以解除瀏覽器端的跨域訪問限制

注意:

  1. CORS 主要在伺服器端進行配置。客戶端瀏覽器無須做任何額外的配置,即可請求開啟了 CORS 的介面
  2. CORS 在瀏覽器中有相容性。只有支援 XMLHttpRequest Level2 的瀏覽器,才能正常訪問開啟了 CORS 的服務端介面(例如:IE10+Chrome4+FireFox3.5+

使用cors解決跨域問題

使用 cors 中介軟體解決跨域問題

  1. cors 是 Express 的一個第三方中介軟體。通過安裝和配置 cors 中介軟體,可以很方便地解決跨域問題
  2. 使用步驟
    • 安裝中介軟體: npm install cors
    • 匯入中介軟體: const cors = require('cors')
    • 配置中介軟體: 在路由之前呼叫app.use(cors())
// 匯入 express 模組
const express = require('express')

// 建立 express 的伺服器例項
const app = express()

// 匯入中介軟體
const cors = require('cors')
// 配置中介軟體
app.use(cors())

// 配置解析表單資料的中介軟體
app.use(express.urlencoded({ extended: false }))

// 匯入路由模組
const router = require('./020-apiRouter')
// 把路由模組,註冊到 app 上
app.use('/api', router)

// 呼叫 app.listen 方法,指定埠號並啟動 web 伺服器
app.listen(3000, () => {
  console.log('running……')
})

cors請求的分類

客戶端在請求 CORS 介面時,根據請求方式和請求頭的不同,可以將 CORS 的請求分為兩大類,分別是:

  • 簡單請求
  • 預檢請求
簡單請求

同時滿足以下兩大條件的請求,就屬於簡單請求

  • 請求方式GETPOSTHEAD 三者之一
  • HTTP 頭部資訊不超過9種欄位
預檢請求
  1. 只要符合以下任何一個條件的請求,都需要進行預檢請求
  • 請求方式為 GETPOSTHEAD 之外的請求 Method 型別
  • 請求頭中包含自定義頭部欄位
  • 向伺服器傳送了 application/json 格式的資料

在瀏覽器與伺服器正式通訊之前,瀏覽器會先傳送 OPTION 請求進行預檢,以獲知伺服器是否允許該實際請求,所以這一次的 OPTION 請求稱為“預檢請求”。伺服器成功響應預檢請求後,才會傳送真正的請求,並且攜帶真實資料

相關文章