iT邦幫忙

2022 iThome 鐵人賽

DAY 28
0
Modern Web

小白大戰基礎網頁開發系列 第 28

D28 - 淺談 Node.js - POST & Middleware & Multer

  • 分享至 

  • xImage
  •  

POST

    var express = require('express');
    var app = express();
    var PORT = 8080;
    app.post('/handle', (req, res) => {
      res.send("POST Request")
    })
      
    app.listen(PORT, function(err){
        if (err) console.log(err);
        console.log("Server listening on PORT", PORT);
    }); 

Output:

使用者上傳的圖片:image.png

使用 Postman 發送 POST Request:

POST 參數:

對於昨天介紹的 GET 端點, 我們使用 req.paramsreq.query 來獲得在請求 URL 中傳遞的端點參數。今天要介紹的 POST 端點, 是來獲得指定的資訊, 比如會員登入(執行某個動作), 資訊放在 request body 裡面, POST 請求是在 request body 中傳送參數, 而 不是在 URL 中。因為 GET 只是單純跟 server 拿取資訊, 比如索取一個圖片或連結, 所以沒有 request body 的存在。

    app.post("/hello", (req, res) => {
      let name = req.params.name; // 此法行不通!
      /* ... */
    });

不過, 在 URL 中傳送參數有什麼缺點呢?

  • 不安全, 會限制我們可以在 URL 中傳送的數據長度

那麼, 我們該如何獲取客戶端發送的 POST 參數呢?

處理不同的 POST Requests

可以使用不同的數據類型 (data type) 發送 POST 請求, 而 POST 請求通常是透過 HTML form 來傳送的:

  • application/x-www-form-urlencoded: 表單內容會都以 url encoded 的方式被傳送, 也是表單預設的提交數據類型
  • application/json: 請求內容是 JSON 數據格式
  • multipart/form-data: 用於在表單中上傳文檔

參考文件: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST

在 Express 中, 我們必須使用中介軟體 (middleware) 從 req.body 中提取 POST 參數。
通過表單 (forms) 和 fetch, 我們使用 FormData 物件發送 POST 參數, 該參數始終作為 multipart/form-data 來傳送。沒有內建的中介軟體可以訪問 multipart 內容的 req.body 參數。
multipart/form-data: 使用者可以透過單一個請求一次傳送複數個資料格式出去, 它主要用在 HTML 的表單裡

Middleware Pipeline

Middleware 中文也稱中介軟體, 是指在客戶端發出請求 (request) 後, 一直到接收響應 (response) 這段一來一回的路程中, 被拿來處理特定用途的程式。而我們已經使用過的 app.get( ) 和 app.post( ) 即是 middleware。這個一來一回的路程中, 就像 Pipeline (管線) 一樣, 所以 ASP.NET Core 使用了 middleware 所行成的 pipeline 去處理 HTTP 的請求 (request) 和響應 (response) 而替換掉原本的 HTTP Modules 和 HTTP Handlers。

中介軟體為組成應用程式管線的軟體,用以處理要求與回應。 每個元件:
- 可選擇是否要將要求傳送到管線中的下一個元件。
- 可以下一個元件的前後執行工作。

圖片和資訊參考引用自: ASP.NET Core 中介軟體

Multer 模組

用於提取透過 multipart POST 請求發送的 POST 參數值的模組, 例如使用 FormData 發送的那些有很多是支持文件上傳的功能, 但我們只會使用它來訪問透過 FormData 發送的 POST 請求 body, 然而僅使用 req.body 是無法獲得的。我們需要使用 multer().none() 設定一個選項以忽略上傳功能去使用。
簡單來說, 如果使用者想要上傳圖片就會發出 POST 請求, 而圖片檔會以 FormData 的格式傳到後端, 此時 multer 模組就會幫使用者處理接收到的請求資料。

請先在 project 中運行 npm install multernpm install multer --``save

    // 引入 Multer 
    const multer = require("multer");
    app.use(multer().none());


    // 引入其他 required modules ...
    const multer = require("multer");
    
    // for application/x-www-form-urlencoded
    // built-in middleware
    app.use(express.urlencoded({ extended: true })); 
    
    // for application/json
    // built-in middleware
    app.use(express.json());
     
    // for multipart/form-data (FormData 需要的)
    // 需要使用 "multer" module
    app.use(multer().none()); 

multer( ): Node.js 中介軟體 (middleware), 負責處理 multipart/form-data 格式資料, 通常用於上傳檔案
multer( ).none( ): 當你只需要處理 value-only 的 multipart 表單時, 可以使用.none( )

處理 POST Reqeust 小總結:

  1. 使用 app.post 而不是 app.get
  2. 使用 req.body.paramname
    (而不是 req.params.paramname 或 req.query.paramname)
  3. 需要 multer(non-core)模組 和其他模組
  4. 使用三個 middleware 函數來支持來自不同潛在客戶端的三種不同類型的 POST 請求(上述所介紹的 三種數據 類型)
  5. 在客戶端 JS 中使用或使用 fetch 和 FormData 測試你的 POST 請求, 並且記得不能在 URL 中測試 POST 請求喔!

上一篇
D27 - 實作 Node.js Project
下一篇
D29 - Databases 資料庫
系列文
小白大戰基礎網頁開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言