--- title: 'Express 教學 6: 使用表單' slug: Learn/Server-side/Express_Nodejs/forms translation_of: Learn/Server-side/Express_Nodejs/forms ---
{{LearnSidebar}}
{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/Displaying_data", "Learn/Server-side/Express_Nodejs/deployment", "Learn/Server-side/Express_Nodejs")}}

在此教程中,我們會教你如何使用 Express ,並且結合 Pug 來實現 HTML 表單,並且如何從數據庫中創建、更新、和刪除文檔。

前提條件: 完成前面所有的教程,包括 Express 教程第5章: 展示圖書館數據。
目標: 了解如何編寫表單獲取用戶信息,並且將這些數據更新到數據庫中。

概覽

HTML 表單是網頁中由一個、或多個字段/小工具形成的一個組合,它被用來收集用戶的信息,並將信息上傳到服務器。表單作為一種用來收集用戶的機制,非常的靈活,因為有各種合適的輸入框,來接受各種類型的數據——文本框,複選框,單選按鈕,時間選擇器等。表單和服務器交互數據也相對安全,因為它使用POST請求發送數據,保護不受跨站點請求偽造攻擊(cross-site request forgery)的威脅。

但是表單同樣也很複雜!開發者需要編寫給表單編寫 HTML,在服務器上驗證,並且正確去除有害的數據(瀏覽器上也可能需要),對於任何不合法的字段,需要傳給用戶相應的錯誤信息,當數據成功提交後,處理數據,並設法通知用戶提交成功。

此教程將展示上述的操作,如何在 Express 中實現。在此過程中,我們將擴展 LocalLibrary 網站,以允許用戶創建、編輯、和刪除圖書館中的項目。

注意: 我們還沒有考慮如何將特定路由,限制為經過身份驗證或授權的用戶,因此在這個時間點,任何用戶都可以對數據庫進行更改。

HTML 表單

首先簡要概述 HTML 表單。考慮一個簡單的 HTML 表單,其中包含一個文本字段,用於輸入某些 “團隊” 的名稱,及其相關標籤:

Simple name field example in HTML form

表單在HTML中,定義為 <form>...</form>標記內的元素集合,包含至少一個type="submit"input輸入元素。

<form action="/team_name_url/" method="post">
    <label for="team_name">Enter name: </label>
    <input id="team_name" type="text" name="name_field" value="Default name for team.">
    <input type="submit" value="OK">
</form>

雖然這裡,我們只包含一個(文本)字段,用於輸入團隊名稱,但表單可能包含任意數量的其他輸入元素,及其相關標籤。字段的 type 屬性,定義將顯示哪種窗口小部件。該字段的名稱nameid ,用於標識JavaScript/CSS/HTML 中的字段,而 value定義字段首次顯示時的初始值。匹配團隊標籤使用 label 標籤,指定(請參閱上面的“輸入名稱” "Enter name"),其中 for 字段,包含 input 相關輸入的 id值。

提交輸入(submit)將顯示為按鈕(默認情況下) - 用戶可以按此按鈕,將其他輸入元素包含的數據,上傳到服務器(在本例中,只有 team_name)。表單屬性,定義用於發送數據的HTTP method方法,和服務器上數據的目標(action):

表單處理流程

表單處理使用的技術,與我們學習過、用來顯示有關模型的信息的所有技術,是相同的:路由將我們的請求發送到控制器函數,該函數執行所需的任何數據庫操作,包括從模型中讀取數據,然後生成並返回 HTML 頁面。使事情變得更複雜的是,服務器還需要能夠處理用戶提供的數據,並在出現任何問題時,重新顯示帶有錯誤信息的表單。

下面顯示了處理表單請求的流程圖,從包含表單的頁面請求開始(以綠色顯示):

如上圖所示,構成處理代碼所需要做的主要是:  

  1. 在用戶第一次請求時顯示默認表單。
  2. 接收用戶提交的數據,通常是在HTTP POST請求中。
  3. 驗證並清理數據。
  4. 如果任何數據無效,請重新顯示表單 - 這次使用用戶填寫的任何值,和問題字段的錯誤消息。
  5. 如果所有數據都有效,請執行所需的操作(例如,將數據保存在數據庫中,發送通知電子郵件,返回搜索結果,上傳文件等)
  6. 完成所有操作之後,將用戶重定向到另一個頁面。

表格處理代碼,通常使用 GET路由,以實現表單的初始顯示,以及 POST路由到同一路徑,以處理表單數據的驗證和處理。這是將在本教程中使用的方法!

Express 本身不提供表單處理操作的任何特定支持,但它可以使用中間件,以處理表單中的 POSTGET參數,並驗證/清理它們的值。

驗證和清理

在儲存表單中的數據之前,必須對其進行驗證和清理:

在本教程中,我們將使用流行的 express-validator 模塊,來執行表單數據的驗證和清理。

安裝

通過在項目的根目錄中,運行以下命令,來安裝模塊。

npm install express-validator

使用 express-validator

注意: Github上的 express-validator 指南,提供了API的良好概述。我們建議您閱讀該內容,以了解其所有功能(包括創建自定義驗證程序)。下面我們只介紹一個對 LocalLibrary 有用的子集。

 

 

要在我們的控制器中使用驗證器,我們必須從 'express-validator/check'和'express-validator/filter'模塊中,導入我們想要使用的函數,如下所示:

const { body,validationResult } = require('express-validator/check');
const { sanitizeBody } = require('express-validator/filter');

有許多可用的功能,允許您一次檢查和清理請求參數,正文,標頭,cookie 等數據,或所有數據。對於本教程,我們主要使用 bodysanitizeBody,和 validationResult(如上面 required 導入的 )。

功能定義如下:

驗證和清理鏈,是應該傳遞給 Express 路由處理程序的中間件(我們通過控制器,間接地執行此操作)。中間件運行時,每個驗證器/清理程序都按指定的順序運行。

當我們實現下面的LocalLibrary表單時,我們將介紹一些真實的例子。

表單設計

圖書館中的許多模型都是相關/依賴的 - 例如,一本書需要一個作者,也可能有一個或多個種類。這提出了一個問題,即我們應該如何處理用戶希望的情況:

在這個項目,我們為了簡化實作,將聲明表單只能:

注意: 更“牢固”的實現,可能允許您在創建新對象時,創建依賴對象,並隨時刪除任何對象(例如,通過刪除依賴對象,或從數據庫中,刪除對已刪除對象的引用) 。

路由

為了實現我們的表單處理代碼,我們需要兩個具有相同 URL 模式的路由。

第一個(GET)路由,用於顯示用於創建對象的新空表單。第二個路由(POST),用於驗證用戶輸入的數據,然後保存信息,並重定向到詳細信息頁面(如果數據有效),或重新顯示有錯誤的表單(如果數據無效)。

我們已經在 /routes/catalog.js(在之前的教程中)為我們所有模型的創建頁面,創建了路徑。例如,種類路由如下所示:

// GET request for creating a Genre. NOTE This must come before route that displays Genre (uses id).
router.get('/genre/create', genre_controller.genre_create_get);

// POST request for creating Genre.
router.post('/genre/create', genre_controller.genre_create_post);

Express 表單子文件

以下子文件,將帶我們完成向示例應用程序添加所需表單的過程。在進入下一個文件之前,您需要依次閱讀並解決每個問題。

  1. 創建種類表單 — 定義我們的頁面以創建種類對象 Genre
  2. 創建作者表單 — 定義用於創建作者對象 Author 的頁面。
  3. 創建書本表單 — 定義頁面/表單以創建書本對象 Book
  4. 創建書本實例表單 — 定義頁面/表單以創建書本實例對象 BookInstance
  5. 刪除作者表單 — 定義要刪除作者對象 Author 的頁面。
  6. 更新書本表單 — 定義頁面以更新書本對象 Book

挑戰自我

實現 Book, BookInstance, 和 Genre模型的刪除頁面,用跟我們的作者刪除頁面相同的方式,將它們與關聯的詳細信息頁面,鏈接起來。頁面應遵循相同的設計方法:

一些提示:

實現 BookInstance, Author, 和 Genre模型的更新頁面,以與我們的書本更新頁面相同的方式,將它們與關聯的詳細信息頁面,鏈接起來。

一些提示:

總結

Express, node, 與NPM上面的第三方套件,提供你需要的每樣東西 ,可用於新增表單到你的網站上。在本文中,您學習如何使用 Pug 創建表單,使用 express-validator 驗證和清理輸入,以及添加,刪除和修改數據庫中的記錄。

你現在應該了解如何新增基本表單,以及表單處理代碼到你的 node 網站!

請參閱

{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/Displaying_data", "Learn/Server-side/Express_Nodejs/deployment", "Learn/Server-side/Express_Nodejs")}}

本教程連結