Below I will bring you an article that perfectly solves the problem of Session failure during ajax access. Let me share it with you now and give it as a reference for everyone.
Recently due to a project, the module switched to ajax request data. When the Session expired, there was no return value after the ajax request, only the response html:
Now Ajax is in the web project It is widely used and can be said to be almost everywhere, which brings another question: What should you do when an Ajax request encounters a Session timeout?
Obviously, the traditional page jump is no longer applicable here, because the Ajax request is initiated by the XMLHTTPRequest object rather than the browser. The page jump after the verification fails cannot be reflected in the browser because the server returns (or output) information is received by JavaScript (XMLHTTPRequest object).
So how should we deal with this situation?
Method
Since the message returned by the server is received by the XMLHTTPRequest object, and the XMLHTTPRequest object is under the control of JavaScript, then do we Can JavaScript be used to complete page jumps?
Of course you can, and it’s easy to do! But one thing is that we need to determine whether the HTTP request is an Ajax request (because AJAX requests and ordinary requests need to be processed separately), how to determine this? In fact, Ajax requests are different from ordinary HTTP requests, which is reflected in the header information of the HTTP request, as shown below:
The above two pictures are using Intercepted by Firefox's Firebug, the former is ordinary HTTP request header information; the latter is the request header information of Ajax request. Pay attention to the part surrounded by the red box in the first picture. This is where the Ajax request is different from the ordinary request. The AJAX request header contains the X-Requested-With information, and its value is XMLHttpRequest. This is what we can take advantage of.
Let’s take a look at how the code is implemented.
Interceptor filter
When using Struts2, we generally use Interceptor (interceptor) to intercept permission issues.
Part of the interceptor code:
public String intercept(ActionInvocation invocation) throws Exception { // TODO Auto-generated method stub ActionContext ac = invocation.getInvocationContext(); HttpServletRequest request = (HttpServletRequest) ac.get(StrutsStatics.HTTP_REQUEST); String requestType = request.getHeader("X-Requested-With"); System.out.println("+++++++++++++++++++++++reqestType:"+requestType); HttpServletResponse response = (HttpServletResponse) ac.get(StrutsStatics.HTTP_RESPONSE); // String basePath = request.getContextPath(); String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path; //获取session Map session = ac.getSession(); //判断session是否存在及session中的user信息是否存在,如果存在不用拦截 if(session != null && session.get(Constants.FE_SESSION_BG_USER) != null && session.get(Constants.FE_SESSION_BG_AUTH) != null){ System.out.println(invocation.getProxy().getActionName()+"++++++++++++++++++++++++"); System.out.println("namespace:"+invocation.getProxy().getNamespace()); //访问路径 String visitURL = invocation.getProxy().getNamespace() + "/" + invocation.getProxy().getActionName() + Constants.FE_STRUTS_ACTION_EXTENSION; visitURL = visitURL.substring(1); Map<String , Object> authMap = (Map<String, Object>) session.get(Constants.FE_SESSION_BG_AUTH); Map<Integer, String> actionMap = (Map<Integer, String>) authMap.get(Constants.FE_BG_ACTIONMAP); if(actionMap != null && !actionMap.isEmpty() && visitURL != null){ if (actionMap.containsValue(visitURL)) { System.out.println(visitURL+"-----------------------"); return invocation.invoke(); } else{ String forbidden = basePath + Constants.FE_BG_FORBIDDEN; response.sendRedirect(forbidden); return null; } } return invocation.invoke(); }else{ if(StringUtils.isNotBlank(requestType) && requestType.equalsIgnoreCase("XMLHttpRequest")){ response.setHeader("sessionstatus", "timeout"); response.sendError(518, "session timeout."); return null; }else { String actionName = invocation.getProxy().getActionName(); System.out.println(actionName); //如果拦截的actionName是loginUI或login,则不做处理,否则重定向到登录页面 if (StringUtils.isNotBlank(actionName) && actionName.equals(Constants.FE_BG_LOGINUI)) { return invocation.invoke(); }else if(StringUtils.isNotBlank(actionName) && actionName.equals(Constants.FE_BG_LOGIN)){ return invocation.invoke(); }else{ String login = basePath + "/" + Constants.FE_BG_LOGIN_NAMESPACE + "/" + Constants.FE_BG_LOGINUI + Constants.FE_STRUTS_ACTION_EXTENSION; // System.out.println("+++++++++++++++++++++++++++basePath:"+basePath); // response.sendRedirect(login); PrintWriter out = response.getWriter(); // out.println("<html>"); // out.println("<script>"); // out.println("window.open ('"+login+"','_top');"); // out.println("</script>"); // out.println("</html>"); out.write("<html><script type='text/javascript'>window.open('"+login+"','_top');</script></html>"); return null; } } } }
As can be seen from the above code, when the Session verification fails (that is, the Session times out), we obtain the request header information X through HttpServletRequest If the value of -Requested-With is not empty and equal to XMLHttpRequest, then it means that the request is an Ajax request. Our response is to add a header information (customized) to the response and make the response object HttpServletResponse return server error information. (The 518 status is defined by you at will); these information will be received by JavaScript, so the following work will be done by JavaScript code.
Javascript code
$.ajaxSetup method is used to set the default options for AJAX requests. We can think of it as a global option setting, so it can Add this code to an external JS file and reference it on the required page.
/** * 设置未来(全局)的AJAX请求默认选项 * 主要设置了AJAX请求遇到Session过期的情况 */ $.ajaxSetup({ type: 'POST', complete: function(xhr,status) { var sessionStatus = xhr.getResponseHeader('sessionstatus'); if(sessionStatus == 'timeout') { var top = getTopWinow(); var yes = confirm('由于您长时间没有操作, session已过期, 请重新登录.'); if (yes) { top.location.href = '/skynk/index.html'; } } } }); /** * 在页面中任何嵌套层次的窗口中获取顶层窗口 * @return 当前页面的顶层窗口对象 */ function getTopWinow(){ var p = window; while(p != p.parent){ p = p.parent; } return p; }
The above is what I compiled for everyone. I hope it will be helpful to everyone in the future.
Related articles:
The reasons and solutions why ajax internal values cannot be called externally
Use Nginx reverse proxy to avoid ajax cross Domain request method
Comprehensive analysis of Ajax comprehensive application
The above is the detailed content of Perfectly solve the problem of Session failure when accessing Ajax. For more information, please follow other related articles on the PHP Chinese website!