Http請求狀態碼302,已得到html頁面但未跳轉?HttpServletRequest轉發/HttpServletResponse重定向后,前端頁面未跳轉?Ajax怎么處理頁面跳轉?


直接看【問題概述】,和最后的【真·最終解決】就可以了

問題概述

事情是這樣的,我在用Java開發后端。前端頁面使用jQuery庫的 $.getJSON() 方法發送了一個Ajax請求

添加過濾器跳轉之前前端效果正常。

但是當我在后端加上了一個判斷用戶是否已經登錄的Filter過濾器時,出現了問題!

過濾器功能很簡單:

  • 用戶已經登錄:請求順利通過過濾器;
  • 用戶還沒有登錄:過濾器通過請求或響應響應的對象進行跳轉。

增加過濾器后的結果:

  • 登錄狀態:前端頁面依然正常顯示數據。
  • 非登錄狀態:頁面既沒有顯示數據也沒有跳轉!
    • 此時打開瀏覽器后台查看:
      • 請求的狀態碼為302
      • 瀏覽器后台已獲取到需要跳轉的頁面,但是前端當前頁面卻沒有改變


出錯圖(1)👇


出錯圖(2)👇


問題分析

排除問題

  • 非后端的問題:
    1. 以前實多次使用過濾器跳轉並沒有出現問題
    2. 前端確實收到了跳轉頁面,只不過沒有顯示
  • 通過測試排除一些其他問題:
    1. 具體排除了什么不記得了

逼近真相

  • 排除了后端問題后,我開始在網上搜索前端問題的解決方案(我對前端不熟悉)。
  • 逐漸的我將問題鎖定在Ajax請求和$.getJSON()方法上。
  • 看到網上說Ajax不適合做跳轉,並提供的Ajax實現跳轉的方法,然而並不適合我的代碼。
  • 又看到了有人說,可以在請求方法后面加上window.location='/'實現跳轉,我試了,這種跳轉是無差別的跳轉。也就是說在登錄狀態下成功返回JSON數據是也是會跳轉的!這顯然不是我想要的結果。

到這里,答案已經十分接近了。也就是在返回JSON的時候不跳轉,返回html的時候跳轉。

但是當我在查怎么知道Ajax返回結果的時候卡住,沒有找到滿意的答案。

正在愁呢,突然就想起一件事情:也許$.getJSON()方法是是有返回值的!於是我嘗試接收了這個返回值,並用consle.log()在控制台記錄這個對象。果然,出現了一個包含很多信息的對象!

最終解決(假)

我分別測試了,登錄狀態和未登錄狀態下$.getJSON()方法的返回對象。在仔細對比后發現了其中的不同!

我發現這個對象有一個屬性statusText:

  • ajax請求得到了正確響應時:即得到了JSON對象,statusText屬性的值為"success";

  • ajax請求得到了錯誤響應時:即沒有得到JSON對象,而是得到一個html,statusText屬性的值為"parsererror"

    parser error : 分析器錯誤

“神秘對象”截圖👇


解決方案:很簡單,只要獲得“神秘對象”並判斷statusText屬性值區別處理!

代碼:不過彩筆的我還是因為不熟悉JavaScript,被JavaScript的函數執行順序、變量作用域折磨了半天,最終狼狽的解決了問題。

  • 前端頁面Ajax請求部分代碼
<script>
    $(function () {
        //定義一個執行Ajax請求並能獲取Ajax函數返回值的函數
        let ajaxFunction = function () {
            //發起Ajax請求,並把返回值直接return出去
            return $.getJSON("/wx/expressList.do", null, function (data) {
                //如果沒有返回JSON對象,就不會執行回調函數
                //回調函數具體代碼,與問題無關
                //... ...
            });
        }
        //執行上面定義的函數,並判斷Ajax響應是否為json
        if (ajaxFunction().statusText !== 'success'){
            //響應結果不是json,在本例中不是json那就只能時html了!
            window.location = '/';
            //或者使用下面的語句,效果完全相同
            //window.location = '/wx/expressList.do';
        }
    })
</script>
  • 后端過濾器代碼(不重要)
@WebFilter({"/wx/expressList.do", "其他請求"})
public class UserAccessFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) servletRequest;
        HttpServletResponse resp = (HttpServletResponse) servletResponse;
        //判斷用戶是否已經登錄的實現代碼
        boolean isLoggedIn = ... ;
        //到這兒是判斷用戶是否已經
        if (isLoggedIn) {
            //用戶已登錄,請求通過
            filterChain.doFilter(req, resp);
        } else {
            //跳轉(重定向)至登錄頁面
            resp.sendRedirect("/login.html");//這里使用req跳轉(轉發)也可以
        }
    }

    @Override
    public void destroy() {}

真·最終解決

后來又經過測試,發現上面的方法有時候行,有時候不行。

上面方法不行的原因

  • Ajax異步。因為異步導致if條件取值早於return $.getJSON(),那么if條件獲取的值是總是undefined!當然也有例外,這跟編譯器和執行環境等因素有關。

最終方案:

  • 換一個Ajax請求方法,苦笑~

  • 使用error回調函數來解決跳轉的問題。

    //ajax請求成功回調函數
    function success(json) {
        //具體實現
    }
    
    //ajax請求失敗回調函數
    function error() {
        //如果返回的是html頁面,打開此頁面
        window.location = "/";
        /*	等效語句
         *	window.location = url;
         */
    }
    
    $.ajax({
        type: 'get',
        url: url,
        dataType: 'json',
        success: success,
        error: error
    });
    
  • success:當ajax請求成功返回JSON對象時才會執行

  • error:當ajax請求失敗時才會執行


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM