常見的 HTTP 方法
以下是常見的 HTTP 方法及其用途:
-
GET:用來從伺服器取得資源(例如取得一筆資料、列表或檔案)。這是最常用的方法,通常用於查詢資料。
-
POST:用來向伺服器送出資料,通常用於創建新資源(例如新增一筆資料到資料庫)。
-
PUT:用來更新伺服器上的資源,通常是將現有資源的全部內容替換。
-
PATCH:類似 PUT,但用來部分更新資源,只修改指定欄位。
-
DELETE:用來從伺服器刪除資源(例如刪除一筆資料)。
-
OPTIONS:用來查詢伺服器支援的 HTTP 方法,通常用於 CORS(跨來源資源共享)預檢請求。
-
HEAD:與 GET 類似,但只回傳標頭(header),不回傳主體內容,通常用來檢查資源是否存在或取得元資料。
在 React 中使用 HTTP 方法
在 React 中,我們通常使用 JavaScript 的 fetch API 或第三方套件(如 axios)來發送 HTTP 請求。以下我會以 fetch 為例,展示如何在 React 專案中使用不同的 HTTP 方法與後端 API 互動。為了讓你容易理解,我會提供完整的程式碼,並逐步解釋每個步驟。
前提準備
假設你已經有一個 React 專案,並有一個後端 API 可以接受請求(例如一個簡單的 REST API)。以下範例假設後端 API 的基礎 URL 是 https://api.example.com,並有一個users 端點可以用來管理使用者資料。
如果你還沒有後端 API,可以使用免費的模擬 API 服務(如 JSONPlaceholder)來測試。
範例 1:使用 GET 方法取得使用者列表
情境:你想從後端 API 取得所有使用者的列表,並顯示在 React 頁面上。
程式碼
import React, { useState, useEffect } from "react";
function UserList() {
// 使用 useState 來儲存從 API 取得的資料
const [users, setUsers] = useState([]);
// 使用 useState 來處理載入狀態
const [loading, setLoading] = useState(true);
// 使用 useState 來處理錯誤訊息
const [error, setError] = useState(null);
// 使用 useEffect 在元件載入時發送 GET 請求
useEffect(() => {
// 定義非同步函數來取得資料
async function fetchUsers() {
try {
// 使用 fetch 發送 GET 請求
const response = await fetch(
"https://jsonplaceholder.typicode.com/users"
);
// 檢查是否成功
if (!response.ok) {
throw new Error("無法取得使用者資料");
}
// 將回應轉為 JSON 格式
const data = await response.json();
// 更新狀態
setUsers(data);
setLoading(false);
} catch (err) {
// 處理錯誤
setError(err.message);
setLoading(false);
}
}
// 執行非同步函數
fetchUsers();
}, []); // 空陣列表示只在元件首次渲染時執行
// 載入中顯示
if (loading) {
return <div>載入中...</div>;
}
// 錯誤時顯示錯誤訊息
if (error) {
return <div>錯誤:{error}</div>;
}
// 渲染使用者列表
return (
<div>
<h1>使用者列表</h1>
<ul>
{users.map((user) => (
<li key={user.id}>
{user.name} - {user.email}
</li>
))}
</ul>
</div>
);
}
export default UserList;
逐步解釋
-
useState:用來儲存使用者資料 (users)、載入狀態 (loading) 和錯誤訊息 (error)。
-
useEffect:在元件首次渲染時執行 fetchUsers 函數,發送 GET 請求。
-
fetch:使用 fetch 發送 GET 請求到 API 端點。GET 請求不需要額外的配置,直接提供 URL 即可。
-
錯誤處理:檢查回應是否成功 (response.ok),如果失敗則拋出錯誤。
-
渲染:根據 loading 和 error 狀態顯示不同的內容,最後渲染使用者列表。
範例 2:使用 POST 方法新增使用者
情境:你想透過表單讓使用者輸入姓名和電子郵件,並將資料透過 POST 請求送到後端 API。
程式碼
import React, { useState } from "react";
function AddUser() {
// 儲存表單輸入的狀態
const [name, setName] = useState("");
const [email, setEmail] = useState("");
// 儲存提交結果
const [message, setMessage] = useState("");
// 處理表單提交
async function handleSubmit(event) {
event.preventDefault(); // 防止表單預設行為
try {
// 使用 fetch 發送 POST 請求
const response = await fetch(
"https://jsonplaceholder.typicode.com/users",
{
method: "POST", // 指定 HTTP 方法為 POST
headers: {
"Content-Type": "application/json", // 指定資料格式為 JSON
},
body: JSON.stringify({
// 將資料轉為 JSON 字串
name,
email,
}),
}
);
// 檢查是否成功
if (!response.ok) {
throw new Error("新增使用者失敗");
}
// 取得回應資料
const data = await response.json();
setMessage(`新增使用者成功:${data.name}`);
// 清空表單
setName("");
setEmail("");
} catch (err) {
setMessage(`錯誤:${err.message}`);
}
}
return (
<div>
<h1>新增使用者</h1>
<form onSubmit={handleSubmit}>
<div>
<label>姓名:</label>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
</div>
<div>
<label>電子郵件:</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<button type="submit">提交</button>
</form>
{message && <p>{message}</p>}
</div>
);
}
export default AddUser;
逐步解釋
-
表單狀態:使用 useState 儲存表單的輸入值 (name 和 email) 以及提交結果 (message)。
-
fetch 配置:在 fetch 中指定 method: 'POST',並設置 headers 和 body。body 必須是 JSON 字串,因此使用 JSON.stringify 轉換資料。
-
錯誤處理:檢查回應是否成功,並顯示成功或錯誤訊息。
-
表單重置:提交成功後清空表單欄位。
範例 3:使用 PUT 方法更新使用者
情境:你想更新某個使用者的資料(例如姓名),透過 PUT 請求將資料送到後端。
程式碼
import React, { useState } from "react";
function UpdateUser() {
// 假設要更新 ID 為 1 的使用者
const userId = 1;
const [name, setName] = useState("");
const [message, setMessage] = useState("");
async function handleSubmit(event) {
event.preventDefault();
try {
const response = await fetch(
`https://jsonplaceholder.typicode.com/users/${userId}`,
{
method: "PUT", // 指定 HTTP 方法為 PUT
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name,
}),
}
);
if (!response.ok) {
throw new Error("更新使用者失敗");
}
const data = await response.json();
setMessage(`更新使用者成功:${data.name}`);
setName("");
} catch (err) {
setMessage(`錯誤:${err.message}`);
}
}
return (
<div>
<h1>更新使用者</h1>
<form onSubmit={handleSubmit}>
<div>
<label>新姓名:</label>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
</div>
<button type="submit">更新</button>
</form>
{message && <p>{message}</p>}
</div>
);
}
export default UpdateUser;
逐步解釋
-
PUT 請求:與 POST 類似,但使用 method: 'PUT',並指定要更新的資源 URL(例如 /users/1)。
-
資料更新:PUT 通常用來完全替換資源,因此送出的資料會覆蓋指定資源的內容。
-
錯誤處理:與 POST 範例類似,檢查回應並顯示結果。
範例 4:使用 DELETE 方法刪除使用者
情境:你想刪除某個使用者(例如 ID 為 1 的使用者)。
程式碼
import React, { useState } from "react";
function DeleteUser() {
const userId = 1;
const [message, setMessage] = useState("");
async function handleDelete() {
try {
const response = await fetch(
`https://jsonplaceholder.typicode.com/users/${userId}`,
{
method: "DELETE", // 指定 HTTP 方法為 DELETE
}
);
if (!response.ok) {
throw new Error("刪除使用者失敗");
}
setMessage("刪除使用者成功");
} catch (err) {
setMessage(`錯誤:${err.message}`);
}
}
return (
<div>
<h1>刪除使用者</h1>
<button onClick={handleDelete}>刪除 ID {userId} 的使用者</button>
{message && <p>{message}</p>}
</div>
);
}
export default DeleteUser;
逐步解釋
-
DELETE 請求:只需要指定 method: 'DELETE' 和目標資源的 URL。
-
無需 body:DELETE 請求通常不需要送出資料,因此不需要 body。
-
回應處理:檢查是否成功並顯示結果。
使用 axios
如果你覺得 fetch 的語法稍嫌複雜,可以使用 axios 來簡化 HTTP 請求。以下是使用 axios 重寫 GET 範例:
安裝 axios
在終端機中執行:
npm install axios
使用 axios 的 GET 範例
import React, { useState, useEffect } from "react";
import axios from "axios";
function UserListWithAxios() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchUsers() {
try {
const response = await axios.get(
"https://jsonplaceholder.typicode.com/users"
);
setUsers(response.data);
setLoading(false);
} catch (err) {
setError(err.message);
setLoading(false);
}
}
fetchUsers();
}, []);
if (loading) {
return <div>載入中...</div>;
}
if (error) {
return <div>錯誤:{error}</div>;
}
return (
<div>
<h1>使用者列表(使用 axios)</h1>
<ul>
{users.map((user) => (
<li key={user.id}>
{user.name} - {user.email}
</li>
))}
</ul>
</div>
);
}
export default UserListWithAxios;
axios 的優點
-
自動處理 JSON 格式,不需要手動轉換。
-
語法更簡潔,錯誤處理更直觀。
-
支援更多功能,如取消請求、全域設定等。
常見問題與注意事項
-
CORS 問題:
-
如果你的前端和後端不在同一個域名,可能會遇到 CORS(跨來源資源共享)錯誤。確保後端 API 已正確設定 CORS 頭部。
-
如果使用 JSONPlaceholder,這類模擬 API 通常已允許 CORS。
-
-
錯誤處理:
-
始終檢查 response.ok 或使用 try-catch 來處理可能的網路錯誤。
-
可以顯示友好的錯誤訊息,讓使用者知道出了什麼問題。
-
-
安全性:
-
如果 API 需要認證(例如 Bearer Token),需要在 headers 中加入 Authorization。
-
範例:
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`,
}
-
-
效能優化:
-
在 useEffect 中使用空依賴陣列 ([]) 確保只在元件首次渲染時發送請求。
-
如果需要頻繁請求資料,可以考慮使用 setInterval 或其他方式控制請求頻率。
-