经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » AJAX » 查看文章
解决Shiro 处理ajax请求拦截登录超时的问题
来源:jb51  时间:2021/9/6 13:21:20  对本文有异议

Shiro 处理ajax请求拦截登录超时

配置全局ajax配置

  1. $.ajaxSetup({
  2. complete:function(XMLHttpRequest,textStatus){
  3. if(textStatus=="parsererror"){
  4. $.messager.alert('提示信息', "登陆超时!请重新登陆!", 'info',function(){
  5. window.location.href = 'login.jsp';
  6. });
  7. } else if(textStatus=="error"){
  8. $.messager.alert('提示信息', "请求超时!请稍后再试!", 'info');
  9. }
  10. }
  11. });

在js里面配置全局的ajax配置即可!

Shiro session超时页面跳转的处理

问题描述

shiro在管理session后,在session超时会进行跳转,这里有两种情况需要考虑,一种是ajax方式的请求超时,一种页面跳转请求的超时。

本文从这两个方面分别考虑并处理。

ajax请求超时处理

思路:通过Filter后判定,当前是否session超时,超时判定是否是ajax请求,如果是ajax请求,则在response头部设置session-status值,返回到前端读取到相应值后进行处理

后端Filter代码

  1. package com.cnpc.framework.filter;
  2. import org.apache.shiro.SecurityUtils;
  3. import org.apache.shiro.session.Session;
  4. import javax.servlet.*;
  5. import javax.servlet.http.HttpServletRequest;
  6. import javax.servlet.http.HttpServletResponse;
  7. import java.io.IOException;
  8. /**
  9. * * filter过滤器,获取项目路径,设置ajax超时标识
  10. * @author billJiang QQ:475572229
  11. */
  12. public class SystemFilter implements Filter {
  13. public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException,
  14. ServletException {
  15. HttpServletRequest request = (HttpServletRequest) servletRequest;
  16. HttpServletResponse response = (HttpServletResponse) servletResponse;
  17. System.out.println(request.getRequestURL());
  18. String basePath = request.getContextPath();
  19. request.setAttribute("basePath", basePath);
  20. if (!SecurityUtils.getSubject().isAuthenticated()) {
  21. //判断session里是否有用户信息
  22. if (request.getHeader("x-requested-with") != null
  23. && request.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
  24. //如果是ajax请求响应头会有,x-requested-with
  25. response.setHeader("session-status", "timeout");//在响应头设置session状态
  26. return;
  27. }
  28. }
  29. filterChain.doFilter(request, servletResponse);
  30. }
  31. @Override
  32. public void destroy() {
  33. // TODO Auto-generated method stub
  34. }
  35. @Override
  36. public void init(FilterConfig arg0) throws ServletException {
  37. // TODO Auto-generated method stub
  38. }
  39. }

前端通用ajax处理

注意session-status上下文部分

  1. function ajaxPost(url, params, callback) {
  2. var result = null;
  3. var headers={};
  4. headers['CSRFToken']=$("#csrftoken").val();
  5. $.ajax({
  6. type : 'post',
  7. async : false,
  8. url : url,
  9. data : params,
  10. dataType : 'json',
  11. headers:headers,
  12. success : function(data, status) {
  13. result = data;
  14. if(data&&data.code&&data.code=='101'){
  15. modals.error("操作失败,请刷新重试,具体错误:"+data.message);
  16. return false;
  17. }
  18. if (callback) {
  19. callback.call(this, data, status);
  20. }
  21. },
  22. error : function(err, err1, err2) {
  23. console.log("ajaxPost发生异常,请仔细检查请求url是否正确,如下面错误信息中出现success,则表示csrftoken更新,请忽略");
  24. console.log(err.responseText);
  25. if(err && err.readyState && err.readyState == '4'){
  26. var sessionstatus=err.getResponseHeader("session-status");
  27. if(sessionstatus=="timeout"){
  28. //如果超时就处理 ,指定要跳转的页面
  29. window.location.href=basePath+"/" ;
  30. }
  31. else{//csrf异常
  32. var responseBody = err.responseText;
  33. if (responseBody) {
  34. responseBody = "{'retData':" + responseBody;
  35. var resJson = eval('(' + responseBody + ')');
  36. $("#csrftoken").val(resJson.csrf.CSRFToken);
  37. this.success(resJson.retData, 200);
  38. }
  39. return;
  40. }
  41. }
  42. modals.error({
  43. text : JSON.stringify(err) + '<br/>err1:' + JSON.stringify(err1) + '<br/>err2:' + JSON.stringify(err2),
  44. large : true
  45. });
  46. }
  47. });
  48. return result;
  49. }

非ajax请求超时跳转

在本试验中,使用jquery.load方式进行了页面加载,并重载jquery.fn.load改写了该方法,通过beforeSend去除了ajax标识,由于超时返回的登录页面可能嵌入当前页面,所以需要判断当前获得的页面是否是登录页面,如果是登陆页面,则再经过一次跳转到登陆页(或者首页)。

重载的jquery.fn.load方法如下,注意beforeSend和responseText.startWith部分内容。

  1. var _old_load = jQuery.fn.load;
  2. jQuery.fn.load = function( url, params, callback ) {
  3. //update for HANZO, 2016/12/22
  4. if (typeof url !== "string" && _old_load) {
  5. return _old_load.apply( this, arguments );
  6. }
  7. var selector, type, response,
  8. self = this,
  9. off = url.indexOf( " " );
  10. if ( off > -1 ) {
  11. selector = jQuery.trim( url.slice( off ) );
  12. url = url.slice( 0, off );
  13. }
  14. if ( jQuery.isFunction( params ) ) {
  15. callback = params;
  16. params = undefined;
  17. } else if ( params && typeof params === "object" ) {
  18. type = "POST";
  19. }
  20. if ( self.length > 0 ) {
  21. jQuery.ajax( {
  22. url: url,
  23. beforeSend: function( xhr ) {
  24. xhr.setRequestHeader('X-Requested-With', {toString: function(){ return ''; }});
  25. },
  26. type: type || "GET",
  27. dataType: "html",
  28. data: params
  29. } ).done( function( responseText ) {
  30. //console.log(responseText);
  31. response = arguments;
  32. //页面超时跳转到首页
  33. if(responseText.startWith("<!--login_page_identity-->")){
  34. window.location.href=basePath+"/";
  35. }else{
  36. self.html(selector ?
  37. jQuery("<div>").append(jQuery.parseHTML( responseText )).find(selector) :
  38. responseText);
  39. }
  40. } ).always( callback && function( jqXHR, status ) {
  41. self.each( function() {
  42. callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
  43. } );
  44. } );
  45. }
  46. return this;
  47. };

可通过设置session的timeout来测试结果。需要注意的是ajax请求要使用ajaxPost方法,该方法统一处理了超时跳转。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号