五種跳轉方式
- RequestDispatcher.forward() - 伺服器端轉發
- response.sendRedirect() - 客戶端重導向
- <jsp:forward page="..." /> - JSP 動作標籤轉發
- <jsp:include page="..." /> - 動態包含(非跳轉,但常混淆)
- JavaScript:
window.location.href - 客戶端腳本跳轉
核心差異深度解析
1. RequestDispatcher.forward()
- 容器內部轉交,請求物件共享,參數/屬性自動傳遞。
- 瀏覽器 URL 不變。
- 無法攜帶查詢字串(
?name=value),需用 request.setAttribute()。
- 無法導向含 Frame 的 JSP,但可導向含 Frame 的 HTML。
- 效能最高,同一應用內首選。
// Servlet 中使用
RequestDispatcher rd = getServletContext().getRequestDispatcher("/index.jsp");
rd.forward(request, response);
2. response.sendRedirect()
- 瀏覽器端 302 跳轉,新請求,原請求資料遺失。
- 瀏覽器 URL 更新為目標 URL。
- 支援跨主機、跨應用、攜帶查詢字串(
/page.jsp?param=value)。
- 可導向含 Frame 的 JSP。
- JSP 頁面可直接用隱含物件
response.sendRedirect()。
// 注意事項
response.sendRedirect("/index.jsp");
return; // 必須立即返回,避免後續輸出導致錯誤
3. <jsp:forward> / <jsp:include>
- 編譯後同樣轉為
RequestDispatcher 呼叫。
forward 終止當前頁面;include 包含後繼續執行。
4. JavaScript 跳轉
- 適用於需在客戶端邏輯判斷後跳轉(如倒數計時、AJAX 成功回調)。
window.location.href = "url"、window.location.replace("url")(不留歷史紀錄)。
效能與選擇策略
| 場景 | 推薦方式 | 理由 |
| 同一應用流程控制、需保留請求資料 | forward / <jsp:forward> | 零網路往返,效能最佳 |
| 登入驗證、跨應用、需更新 URL 書籤 | sendRedirect | 瀏覽器重新請求,符合 REST 語意 |
| 客戶端條件判斷、AJAX 後導向 | JavaScript | 靈活控制時機與目標 |
常見陷阱提醒
sendRedirect 前若有內容輸出且緩衝區已提交(>8KB 或呼叫 flush()),會拋 IllegalStateException。
forward 後原頁面剩餘代碼仍會執行完畢才真正轉發,勿誤以為立即跳出。
- 若需在
forward 目標頁取得資料,請用 request.setAttribute("key", value),而非 Session(除非跨請求共享)。