spring-mvc ajax訪問 session超時 新增攔截
阿新 • • 發佈:2019-01-07
學識尚淺,若有需更正地方,請見諒並留言,謝謝!
我們先了解一下一些必要的資訊。ajax 請求和普通的 http 請求是不一樣的,Ajax請求是XMLHTTPRequest物件發起的,而http請求是瀏覽器發起的。
二者不同地方體現在HTTP請求的頭資訊中。
AJAX請求頭中帶有X-Requested-With資訊,其值為XMLHttpRequest。而普通請求是沒有的。
spring-mvc.xml 配置檔案設定
<!-- 配置攔截器,攔截請求(除了登入ajax請求外攔截全部ajax請求) --> <mvc:interceptors > <mvc:interceptor> <mvc:mapping path="/**"/> <mvc:exclude-mapping path="/admin/login/**"/> <bean class="com.wxc.paycoss.filter.AjaxCheckSession"/> </mvc:interceptor> </mvc:interceptors></span>
說明:其中<bean> 中的 class 是對應包下的攔截器路徑
下面是攔截器 AjaxCheckSession.java (這個類自由命名)
以上程式碼有一些log列印根據自己需要,可以只選其中必須的程式碼package com.wxc.paycoss.filter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import org.springframework.web.util.UrlPathHelper; import com.cvicse.paycoss.base.Const; import com.cvicse.paycoss.domain.Oper; public class AjaxCheckSession extends HandlerInterceptorAdapter{ private final Logger logger = LoggerFactory.getLogger(PaycossContextListener.class); // URL輔助工具類 private UrlPathHelper urlPathHelper = new UrlPathHelper(); @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // TODO Auto-generated method stub super.afterCompletion(request, response, handler, ex); } @Override public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // TODO Auto-generated method stub super.afterConcurrentHandlingStarted(request, response, handler); } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { // TODO Auto-generated method stub super.postHandle(request, response, handler, modelAndView); } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Oper oper = (Oper) request.getSession().getAttribute(Const.SESSION_LOGIN_ADMIN_USER); String requestCTX = urlPathHelper.getContextPath(request); System.out.println(requestCTX); String requestUri = request.getRequestURI(); //請求完整路徑,可用於登陸後跳轉 String contextPath = request.getContextPath(); //專案下完整路徑 String url = requestUri.substring(contextPath.length()); //請求頁面 logger.debug("======攔截器配置成功======"); logger.debug("======攔截來自:"+requestUri+"的請求======="); logger.debug("======攔截的頁面路徑是:==:"+url+"======="); //throw new Exception("登入超時!"); if(oper == null){//如果獲取不到登入的session //如果是ajax請求 if (request.getHeader("x-requested-with") != null && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){ response.setHeader("sessionstatus", "timeout"); // 響應頭設定session狀態 return false; //session超時,ajax訪問返回false } } return super.preHandle(request, response, handler); } }
有了配置檔案,也有了攔截器,在攔截器中已經設定了返回的資訊,而這些資訊會被 javascript 獲取到。
$.ajaxSetup方法是來設定AJAX請求預設選項的,我們可以認為是全域性的選項設定,因此可以將這段程式碼提到外部JS檔案中,在需要的頁面引用。
在這裡不得不說一下 ajaxSetup 中的 contentType ,若不設定,有可能彈出的資訊是中文,但是往往會出現編碼亂碼。/** * 設定未來(全域性)的AJAX請求預設選項 * 主要設定了AJAX請求遇到Session過期的情況 */ $.ajaxSetup({ type: 'POST', contentType:"application/x-www-form-urlencoded;charset=utf-8", complete: function(xhr,status) { var sessionStatus = xhr.getResponseHeader('sessionstatus'); if(sessionStatus == 'timeout') { //var top = getTopWinow(); //var yes = confirm('由於您長時間沒有操作, session已過期, 請重新登入.'); //if (yes) { alert("登入超時,請重新登入!"); window.location.href = '/admin/login/out.do'; //} } } }); /** * 在頁面中任何巢狀層次的視窗中獲取頂層視窗 * @return 當前頁面的頂層視窗物件 */ function getTopWinow(){ var p = window; while(p != p.parent){ p = p.parent; } return p; }