HTTP 3xx 狀態碼與重新導向

更新 2026.09.21

HTTP 狀態碼是伺服器回應客戶端請求時所使用的標準代碼,其中 3xx 代表重新導向(Redirection)。它通常表示目前請求的資源位於其他位置,或客戶端需要進一步操作才能完成請求。

在網站開發與 SEO 中,最常見的重新導向狀態碼包括 301、302、303、307、308,另外還有較少直接用於網址跳轉的 300 與 304。

3xx 狀態碼比較

狀態碼 名稱 主要用途 性質
300 Multiple Choices 同一資源有多個版本可選 多重選擇
301 Moved Permanently 網址永久搬遷 永久重新導向
302 Found 網址暫時搬遷 暫時重新導向
303 See Other POST 完成後前往另一頁查看結果 改用 GET
304 Not Modified 資源沒有修改,可使用快取 快取控制
307 Temporary Redirect 暫時搬遷並保留 HTTP Method 暫時重新導向
308 Permanent Redirect 永久搬遷並保留 HTTP Method 永久重新導向

300 Multiple Choices

300 Multiple Choices 表示同一個請求可能對應多個不同的資源,例如同一份文件同時存在 HTML、PDF、中文版或英文版。伺服器可以回傳多個選擇,讓客戶端自行決定要使用哪一個版本。

這種狀態在一般網站中並不常見。現在多數網站會透過程式邏輯、語言設定或內容協商直接決定要提供哪個版本,而不是讓使用者透過 300 狀態碼選擇。

從 SEO 角度來看,如果網站存在多個相似內容頁面,通常會使用 Canonical、hreflang 或 Redirect 等方式處理,而不是依賴 300。

301 Moved Permanently

301 Moved Permanently 表示原本的資源已經永久移動到新的 URL。

例如:

https://example.com/old-page

永久更改為:

https://example.com/new-page

伺服器可以回傳:

HTTP/1.1 301 Moved Permanently
Location: https://example.com/new-page

301 是網站最常見的 Redirect 類型,適合用於更換網域、HTTP 轉 HTTPS、www 與非 www 統一、文章網址修改、網站目錄結構調整,以及舊頁面永久移動到新頁面的情況。

在 SEO 上,搜尋引擎會逐步把舊 URL 的搜尋訊號轉移到新的 URL,因此網站永久搬遷時通常會使用 301。不過不應簡化成「搜尋權重一定 100% 完整轉移」,實際結果仍會受到頁面內容、Canonical、內部連結、Sitemap 與 Redirect Chain 等因素影響。

301 有一個需要注意的地方:歷史上部分瀏覽器或 HTTP Client 在處理 POST 請求時,可能在 Redirect 後把 POST 改成 GET。如果必須確保原本的 HTTP Method 不變,則應考慮使用 308。

302 Found

302 Found 表示資源目前暫時位於另一個 URL,但原本的 URL 並沒有被永久取代。

例如網站有一個產品頁:

/product

活動期間暫時導向:

/product/summer-sale

就可以使用 302,活動結束後再取消 Redirect。

302 常見於短期活動、維護頁面、A/B Testing、地區導向、登入流程或其他暫時性的頁面切換。

SEO 上,302 傳達的是「原網址只是暫時離開」,因此搜尋引擎通常仍會把原 URL 視為主要網址。不過如果一個 302 長期存在,搜尋引擎也可能根據實際情況重新判斷其性質。

302 和 301 一樣存在 HTTP Method 的歷史相容性問題,因此如果需要保證 POST、PUT 或 PATCH 在 Redirect 後仍維持相同 Method,可以改用 307。

303 See Other

303 See Other 最常出現在表單提交或建立資料之後。它的意思是目前請求已經處理完成,客戶端應該使用 GET 前往另一個 URL 查看結果。

例如:

POST /orders

伺服器建立訂單後回傳:

HTTP/1.1 303 See Other
Location: /orders/123

瀏覽器接下來會:

GET /orders/123

這就是常見的 Post / Redirect / Get(PRG) 模式。

這種方式可以避免使用者在完成表單、留言、付款或建立資料後重新整理頁面時,再次送出相同 POST 請求。

304 Not Modified

304 Not Modified 雖然屬於 3xx,但它並不是一般意義上的網址重新導向,而是 HTTP Cache 機制的一部分。

例如瀏覽器之前已經下載過:

style.css

再次請求時可以附帶:

If-None-Match

或:

If-Modified-Since

如果伺服器確認檔案沒有修改,就可以回傳:

HTTP/1.1 304 Not Modified

此時瀏覽器不需要重新下載完整內容,可以直接使用本地快取,因此能降低流量並提高網站載入速度。

304 常見於 CSS、JavaScript、圖片與其他靜態資源。

307 Temporary Redirect

307 Temporary Redirect 和 302 都代表暫時重新導向,但 307 對 HTTP Method 的規則更明確。

例如原本是:

POST /api/order

收到:

HTTP/1.1 307 Temporary Redirect
Location: /api/order-new

客戶端重新請求時仍然必須使用:

POST /api/order-new

因此 307 特別適合 API、POST、PUT、PATCH 或其他不能隨意改變 HTTP Method 的請求。

簡單來說,302 表示「暫時換網址」,307 則表示「暫時換網址,而且原本的請求方式不能改」。

308 Permanent Redirect

308 Permanent Redirect 與 301 類似,都表示資源已經永久搬遷,但 308 要求 HTTP Method 與 Request Body 必須保留。

例如:

POST /api/v1/order

永久搬到:

POST /api/v2/order

就可以使用:

HTTP/1.1 308 Permanent Redirect
Location: /api/v2/order

因此 308 很適合 API Endpoint 永久搬遷,而一般網頁網址永久調整仍最常使用 301。

301 與 308 的差異

301 與 308 都屬於永久重新導向。主要差異不在 SEO,而是在 HTTP Method 的處理方式。

狀態碼 永久 Redirect 保留原 HTTP Method
301 是 不一定
308 是 是

一般文章或網站頁面永久改網址通常使用 301;如果是 API,且需要確保 POST、PUT、PATCH 等 Method 完整保留,則 308 更適合。

302 與 307 的差異

302 與 307 都屬於暫時重新導向,同樣主要差異在 HTTP Method。

狀態碼 暫時 Redirect 保留原 HTTP Method
302 是 不一定
307 是 是

一般網站臨時活動頁面使用 302 已經足夠;API 或需要保留 Request Body 的請求則較適合使用 307。

重新導向與 SEO

網站修改 URL 時,Redirect 是非常重要的一環。

例如:

http://example.com
→
https://example.com

或者:

https://example.com/old-page
→
https://example.com/new-page

如果這些修改是永久性的,通常使用 301。

除了設定 Redirect,也應同步修改網站內部連結、Canonical 與 Sitemap。不要讓網站內部連結長期指向舊網址,再依靠 301 前往新網址。

例如不理想:

首頁
↓
舊網址
↓ 301
新網址

較好的方式是直接修改成:

首頁
↓
新網址

Redirect Chain

Redirect 不宜經過太多層。

例如:

A
↓ 301
B
↓ 301
C
↓ 301
D

如果 A 最終就是要到 D,最好直接設定:

A
↓ 301
D

過多的 Redirect Chain 會增加 HTTP Request、網站載入時間與搜尋引擎 Crawl 成本,也會讓日後維護更加複雜。

Redirect Loop

設定錯誤時可能出現 Redirect Loop,例如:

A → B
B → A

瀏覽器會不斷在兩個 URL 之間跳轉,最後出現:

Too Many Redirects

網站同時使用 Cloudflare、Nginx、Apache、WordPress 或其他 Reverse Proxy 時尤其容易發生這類問題,因為每一層都可能各自設定 HTTP、HTTPS 或網域 Redirect。

Redirect 與 Canonical

Redirect 和 Canonical 的作用並不完全相同。

Redirect 表示:

舊網址已經不應繼續使用
→ 前往新網址

Canonical 則表示:

這個網址仍然存在
→ 但搜尋引擎應把另一個網址視為主要版本

例如:

<link rel="canonical" href="https://example.com/page">

如果頁面真的已經永久搬遷,應使用 301;如果多個 URL 都需要保留,只是內容高度相似,則可以考慮使用 Canonical。

Redirect 與 Sitemap

Sitemap 應直接列出網站希望搜尋引擎索引的最終 URL。

例如:

/old-page
↓ 301
/new-page

Sitemap 應放:

/new-page

而不是繼續列出:

/old-page

同樣地,網站內部連結也應逐步修改成最終 URL,而不是長期依賴 Redirect。

Nginx 設定範例

HTTP 永久導向 HTTPS:

return 301 https://example.com$request_uri;

單一頁面永久 Redirect:

location = /old-page {
    return 301 /new-page;
}

暫時 Redirect:

return 302 https://example.com/temporary;

Apache 設定範例

使用 .htaccess:

Redirect 301 /old-page https://example.com/new-page

也可以使用:

RewriteEngine On
RewriteRule ^old-page$ /new-page [R=301,L]

PHP 設定範例

301:

header('Location: https://example.com/new-page', true, 301);
exit;

302:

header('Location: https://example.com/temporary', true, 302);
exit;

303:

header('Location: /result', true, 303);
exit;

Laravel 設定範例

一般 Redirect:

return redirect('/new-page');

一般情況下會使用 302。

永久 Redirect:

return redirect()->to('/new-page', 301);

ASP.NET Core 設定範例

暫時 Redirect:

return Redirect("/new-page");

永久 Redirect:

return RedirectPermanent("/new-page");

如果需要保留 HTTP Method,可以使用:

return RedirectPreserveMethod("/new-page");

永久並保留 Method:

return RedirectPermanentPreserveMethod("/new-page");

JavaScript Redirect

JavaScript 也可以執行頁面跳轉:

window.location.href = '/new-page';

但這和 HTTP Redirect 不完全相同。

HTTP Redirect 是伺服器直接回傳:

Request
↓
301 / 302
↓
新網址

JavaScript Redirect 則必須先下載 HTML,再執行 JavaScript:

Request
↓
HTML
↓
JavaScript 執行
↓
新網址

因此如果是網站搬遷或 SEO 用途,通常應優先使用伺服器端的 301、302、307 或 308。

如何選擇狀態碼

最簡單的判斷方式如下:

情況 建議狀態碼
網頁永久改網址 301
網頁暫時改網址 302
POST 完成後前往結果頁 303
暫時 Redirect 且 Method 不可改 307
永久 Redirect 且 Method 不可改 308
資源沒有修改,使用快取 304

一般網站開發最常遇到的是 301 與 302,而在 API 開發中則需要特別理解 307 與 308。

可以簡單記成:

301 = 永久搬家
302 = 暫時搬家
303 = 處理完成後用 GET 看結果
307 = 暫時搬家,但 Method 不變
308 = 永久搬家,但 Method 不變

正確選擇 Redirect 狀態碼,不只會影響瀏覽器的行為,也會影響 API、快取、搜尋引擎索引與網站長期維護,因此應依「是否永久」以及「HTTP Method 是否需要保留」來決定。