今天發現,當使用Ajax請求時,如果后台進行重定向到其他頁面時是無法成功的,只能在瀏覽器地址欄輸入才能夠實現重定向。
Ajax默認就是不支持重定向的,它是局部刷新,不重新加載頁面。
需要實現的功能是,后台網關攔截請求,看請求中是否存在token.如果不存在就跳轉到登錄頁面。因為大多數請求都是使用Ajax.一開始發現無法進行重定向,每次都是返回到Ajax的結果處理函數。最終的解決辦法如下,需要后台和前端進行處理。
后台:
/** *功能描述 * @author lgj * @Description 重定向工具類 * @date 2/27/19 */ @Slf4j public class RedirecUtil { /** *功能描述 * @author lgj * @Description 重定向 * @date 2/27/19 * @param: * @return: * */ public static void redirect(RequestContext ctx, String redirectUrl){ try{ //如果是Ajax請求 if("XMLHttpRequest".equals(ctx.getRequest().getHeader("X-Requested-With"))){ log.debug("ajax redirect"); sendRedirect(ctx.getResponse(),redirectUrl); } //如果是瀏覽器地址欄請求 else { log.debug("normal redirect "); ctx.getResponse().sendRedirect(redirectUrl); } } catch(Exception ex){ ex.printStackTrace(); } } /** *功能描述 * @author lgj * @Description Ajax請求時重定向處理 * @date 2/27/19 * @param: * @return: * */ private static void sendRedirect(HttpServletResponse response, String redirectUrl){ try {
//這里並不是設置跳轉頁面,而是將重定向的地址發給前端,讓前端執行重定向 //設置跳轉地址 response.setHeader("redirectUrl", redirectUrl); //設置跳轉使能 response.setHeader("enableRedirect","true"); response.flushBuffer(); } catch (IOException ex) { log.error("Could not redirect to: " + redirectUrl, ex); } } }
前端處理
第一種方式:使用Ajax的complete方法
$.ajax({ type: "post", url: "/auth/token/check", success: function(data,status){ console.log("/token/check 返回 status : "+status) },
//請求完成調用 (XHR, TS){ console.log("complete"); var url = XHR.getResponseHeader("redirectUrl"); console.log("redirectUrl = " + url); var enable = XHR.getResponseHeader("enaleRedirect");
console.log("enableRedirect = " + enable);
if((enable == "true") && (url != "")){
var win = window;
while(win != win.top){
win = win.top;
}
win.location.href = url;
}
},
});
})
但是上面有個問題就是,每個ajax都需要編寫 comlete 方法,代碼復用率低。
第二種方法 : 使用全局的complete方法
ajax請求
$("#NON-TOKEN").click(function () {
$.ajax({
type: "post",
url: "/auth/token/check",
success: function(data,status){
console.log("/token/check 返回 status : "+status)
},
});
全局處理
注意這參數(event, xhr, settings)不能少,否則會報錯。
//每一個Ajax 請求完成之后都會執行。
$(document).ajaxComplete(function (event, xhr, settings) { console.log("ajaxComplete ") redirectHandle(xhr); })
function redirectHandle(xhr) {
//獲取后台返回的參數 var url = xhr.getResponseHeader("redirectUrl"); console.log("redirectUrl = " + url); var enable = xhr.getResponseHeader("enableRedirect"); if((enable == "true") && (url != "")){ var win = window; while(win != win.top){ win = win.top; } win.location.href = url; }
}
也可以將上述前端代碼放入一個js文件中,在需要進行重定向的時候引入即可,便可以實現更高的代碼復用率。
redirect.js
function redirectHandle(xhr) { var url = xhr.getResponseHeader("redirectUrl"); console.log("redirectUrl = " + url); var enable = xhr.getResponseHeader("enableRedirect"); if((enable == "true") && (url != "")){ var win = window; while(win != win.top){ win = win.top; } win.location.href = url; } } $(function () { $(document).ajaxComplete(function (event, xhr, settings) { console.log("ajaxComplete adffdafadsaf") redirectHandle(xhr); }) })
引入js文件,src根據據實際情況設置。
<script src="/common/redirect.js"></script>
