首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> JSP 程式設計 >> 關於JSP

response.sendRedirect 不跳轉?兩大核心原因與最佳實踐模式

     編輯:關於JSP

現象:代碼執行了 response.sendRedirect(url),控制台無報錯,但瀏覽器網址欄不變、頁面不跳轉。這通常由兩個核心原因導致。

原因一:響應已提交

sendRedirect 原理是發送 HTTP 302 響應頭(Location: url),瀏覽器收到後自動跳轉。一旦響應體開始輸出並刷新到客戶端(Committed),響應頭就無法修改,跳轉失效。

  • JSP 頁面頂部有空白行、HTML 標簽、<%@ include ... %> 引入的文件有輸出。
  • 調用了 out.flush() 或緩衝區自動刷新(默認 8KB)。
  • 在 sendRedirect 前已有大量模板文本輸出。

原因二:跳轉後代碼繼續執行

sendRedirect 不會終止當前線程,後續代碼照常運行,可能再次輸出內容、再次設置響應頭、甚至拋出異常,導致瀏覽器收到混亂響應。

標準修正模式

<%@ page contentType="text/html;charset=UTF-8" %>
<%
    // 1. 業務邏輯判斷
    if (session.getAttribute("user") == null) {
        // 2. 僅在響應未提交前調用
        response.sendRedirect(request.getContextPath() + "/login.jsp");
        // 3. 立即 return,阻斷後續執行
        return;
    }
%>
<!-- 正常頁面內容 -->

進階最佳實踐:統一攔截器/過濾器

不要在每個 JSP 重複判斷,使用 Filter 或 Spring MVC HandlerInterceptor 集中處理:

@WebFilter("/*")
public class AuthFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        String uri = request.getRequestURI();
        // 靜態資源、登錄頁放行
        if (uri.endsWith("login.jsp") || uri.contains("/static/")) {
            chain.doFilter(req, res);
            return;
        }
        if (request.getSession().getAttribute("user") == null) {
            response.sendRedirect(request.getContextPath() + "/login.jsp");
            // Filter 中無需 return,但必須不再調用 chain.doFilter
            return;
        }
        chain.doFilter(req, res);
    }
}

調試技巧:確認響應是否已提交

<%
    System.out.println("isCommitted before redirect: " + response.isCommitted());
    response.sendRedirect("/login.jsp");
    System.out.println("isCommitted after redirect: " + response.isCommitted());
%>

若 before 為 true,說明在此之前已有輸出導致提交,需向上排查模板輸出點。

總結

  1. 前無輸出:確保 sendRedirect 前無任何模板文本、空白行、include 輸出。
  2. 後即返回:調用後立即 return(JSP/Servlet)或不再調用 chain.doFilter(Filter)。
  3. 統一攔截:用 Filter/Interceptor 集中實現登錄校驗與跳轉,消除重複代碼與漏洞。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved