網頁表單 POST 方法
## FastAPI 如何處理表單的 POST 資料
當網頁使用 `<form method="post">` 送出資料時,瀏覽器會將表單欄位放在 HTTP request body 中,而不是放在 URL 的 query string 中。
例如:
```html
<form method="post" action="/login">
<input type="text" name="account">
<input type="password" name="password">
<button type="submit">登入</button>
</form>
```
送出的資料大致如下:
```text
account=user001&password=abc123
```
FastAPI 可以使用 `Form()` 來接收這些表單欄位。
---
## 使用 POST 方法的意義
POST 常用於:
1. **將資料傳送到伺服器**
- 例如登入、註冊、建立訂單、上傳資料。
2. **資料放在 request body**
- 相較於 GET,資料通常不會直接顯示在 URL 上。
- 但這不代表資料自動加密,仍應使用 HTTPS。
3. **可能造成伺服器狀態改變**
- 例如新增會員、修改資料或建立訂單。
4. **可傳送較大量或較複雜的資料**
- 不受 URL 長度限制影響。
> 注意:POST 並不等於安全加密。帳號與密碼傳遞時,正式環境一定要使用 HTTPS,且密碼不應以明文儲存。
---
# 範例:帳號與密碼登入
## 1. 前端 HTML
建立 `login.html`:
```html
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<title>登入</title>
</head>
<body>
<h1>使用者登入</h1>
<form method="post" action="http://127.0.0.1:8000/login">
<div>
<label for="account">帳號:</label>
<input
type="text"
id="account"
name="account"
required
>
</div>
<div>
<label for="password">密碼:</label>
<input
type="password"
id="password"
name="password"
required
>
</div>
<button type="submit">登入</button>
</form>
</body>
</html>
```
重點是:
```html
<input name="account">
<input name="password">
```
`name` 的值必須與後端 FastAPI 函式參數名稱對應。
---
## 2. 後端 FastAPI 程式
建立 `main.py`:
```python
from fastapi import FastAPI, Form
app = FastAPI()
@app.post("/login")
async def login(
account: str = Form(...),
password: str = Form(...)
):
# 範例:實際應從資料庫查詢使用者
if account == "user001" and password == "abc123":
return {
"success": True,
"message": "登入成功",
"account": account
}
return {
"success": False,
"message": "帳號或密碼錯誤"
}
```
---
## 3. 安裝與執行
接收 HTML 表單資料需要安裝 `python-multipart`:
```bash
pip install fastapi uvicorn python-multipart
```
啟動 FastAPI:
```bash
uvicorn main:app --reload
```
接著在瀏覽器開啟 `login.html`,輸入:
```text
帳號:user001
密碼:abc123
```
表單會以 POST 方法呼叫:
```text
http://127.0.0.1:8000/login
```
成功時會收到類似結果:
```json
{
"success": true,
"message": "登入成功",
"account": "user001"
}
```
---
## FastAPI 程式的重點
```python
account: str = Form(...)
password: str = Form(...)
```
說明如下:
- `account`、`password`:接收的表單欄位名稱。
- `str`:將資料視為字串。
- `Form(...)`:表示資料來自 HTML form 的 request body。
- `...`:表示此欄位為必填。
如果前端欄位名稱改成:
```html
<input name="username">
```
後端也必須改成:
```python
username: str = Form(...)
```
否則 FastAPI 無法正確取得該欄位。
實務上還應加入資料庫驗證、密碼雜湊、HTTPS、登入狀態管理,以及 CSRF 防護等安全機制。
相關學習地圖、教學課程
Python 後端工程、資料庫