Shiro 處理ajax請求攔截登錄超時
配置全局ajax配置
1
2
3
4
5
6
7
8
9
10
11
|
$.ajaxSetup({ complete: function (XMLHttpRequest,textStatus){ if (textStatus== "parsererror" ){ $.messager.alert( '提示信息' , "登陸超時!請重新登陸!" , 'info' , function (){ window.location.href = 'login.jsp' ; }); } else if (textStatus== "error" ){ $.messager.alert( '提示信息' , "請求超時!請稍后再試!" , 'info' ); } } }); |
在js里面配置全局的ajax配置即可!
Shiro session超時頁面跳轉(zhuǎn)的處理
問題描述
shiro在管理session后,在session超時會進(jìn)行跳轉(zhuǎn),這里有兩種情況需要考慮,一種是ajax方式的請求超時,一種頁面跳轉(zhuǎn)請求的超時。
本文從這兩個方面分別考慮并處理。
ajax請求超時處理
思路:通過Filter后判定,當(dāng)前是否session超時,超時判定是否是ajax請求,如果是ajax請求,則在response頭部設(shè)置session-status值,返回到前端讀取到相應(yīng)值后進(jìn)行處理
后端Filter代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package com.cnpc.framework.filter; import org.apache.shiro.SecurityUtils; import org.apache.shiro.session.Session; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * * filter過濾器,獲取項(xiàng)目路徑,設(shè)置ajax超時標(biāo)識 * @author billJiang QQ:475572229 */ public class SystemFilter implements Filter { public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; System.out.println(request.getRequestURL()); String basePath = request.getContextPath(); request.setAttribute( "basePath" , basePath); if (!SecurityUtils.getSubject().isAuthenticated()) { //判斷session里是否有用戶信息 if (request.getHeader( "x-requested-with" ) != null && request.getHeader( "x-requested-with" ).equalsIgnoreCase( "XMLHttpRequest" )) { //如果是ajax請求響應(yīng)頭會有,x-requested-with response.setHeader( "session-status" , "timeout" ); //在響應(yīng)頭設(shè)置session狀態(tài) return ; } } filterChain.doFilter(request, servletResponse); } @Override public void destroy() { // TODO Auto-generated method stub } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } } |
前端通用ajax處理
注意session-status上下文部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
function ajaxPost(url, params, callback) { var result = null ; var headers={}; headers[ 'CSRFToken' ]=$( "#csrftoken" ).val(); $.ajax({ type : 'post' , async : false , url : url, data : params, dataType : 'json' , headers:headers, success : function (data, status) { result = data; if (data&&data.code&&data.code== '101' ){ modals.error( "操作失敗,請刷新重試,具體錯誤:" +data.message); return false ; } if (callback) { callback.call( this , data, status); } }, error : function (err, err1, err2) { console.log( "ajaxPost發(fā)生異常,請仔細(xì)檢查請求url是否正確,如下面錯誤信息中出現(xiàn)success,則表示csrftoken更新,請忽略" ); console.log(err.responseText); if (err && err.readyState && err.readyState == '4' ){ var sessionstatus=err.getResponseHeader( "session-status" ); if (sessionstatus== "timeout" ){ //如果超時就處理 ,指定要跳轉(zhuǎn)的頁面 window.location.href=basePath+ "/" ; } else { //csrf異常 var responseBody = err.responseText; if (responseBody) { responseBody = "{'retData':" + responseBody; var resJson = eval( '(' + responseBody + ')' ); $( "#csrftoken" ).val(resJson.csrf.CSRFToken); this .success(resJson.retData, 200); } return ; } } modals.error({ text : JSON.stringify(err) + '<br/>err1:' + JSON.stringify(err1) + '<br/>err2:' + JSON.stringify(err2), large : true }); } }); return result; } |
非ajax請求超時跳轉(zhuǎn)
在本試驗(yàn)中,使用jquery.load方式進(jìn)行了頁面加載,并重載jquery.fn.load改寫了該方法,通過beforeSend去除了ajax標(biāo)識,由于超時返回的登錄頁面可能嵌入當(dāng)前頁面,所以需要判斷當(dāng)前獲得的頁面是否是登錄頁面,如果是登陸頁面,則再經(jīng)過一次跳轉(zhuǎn)到登陸頁(或者首頁)。
重載的jquery.fn.load方法如下,注意beforeSend和responseText.startWith部分內(nèi)容。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
var _old_load = jQuery.fn.load; jQuery.fn.load = function ( url, params, callback ) { //update for HANZO, 2016/12/22 if ( typeof url !== "string" && _old_load) { return _old_load.apply( this , arguments ); } var selector, type, response, self = this , off = url.indexOf( " " ); if ( off > -1 ) { selector = jQuery.trim( url.slice( off ) ); url = url.slice( 0, off ); } if ( jQuery.isFunction( params ) ) { callback = params; params = undefined; } else if ( params && typeof params === "object" ) { type = "POST" ; } if ( self.length > 0 ) { jQuery.ajax( { url: url, beforeSend: function ( xhr ) { xhr.setRequestHeader( 'X-Requested-With' , {toString: function (){ return '' ; }}); }, type: type || "GET" , dataType: "html" , data: params } ).done( function ( responseText ) { //console.log(responseText); response = arguments; //頁面超時跳轉(zhuǎn)到首頁 if (responseText.startWith( "<!--login_page_identity-->" )){ window.location.href=basePath+ "/" ; } else { self.html(selector ? jQuery( "<div>" ).append(jQuery.parseHTML( responseText )).find(selector) : responseText); } } ).always( callback && function ( jqXHR, status ) { self.each( function () { callback.apply( this , response || [ jqXHR.responseText, status, jqXHR ] ); } ); } ); } return this ; }; |
可通過設(shè)置session的timeout來測試結(jié)果。需要注意的是ajax請求要使用ajaxPost方法,該方法統(tǒng)一處理了超時跳轉(zhuǎn)。
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://blog.csdn.net/qq_25223941/article/details/51732667