• 背景
    在开发过程中完成session共享时测试session中断过期页面响应而遇到了问题。

  • 技术使用
    springboot+redis+shiro+静态html分离式前端

首先要弄懂一个问题,为什么服务端写了重定向,前端页面没有去跳转?并且重定向里的请求location也指向清楚了。
因为ajax请求里涉及返回两种类型,一种是返回json,一种是返回页面内容,如果纯粹的返回内容的话就走304,页面去读缓存了,然后重定向在阻塞,导致页面没有刷新,当手工刷新才加载304要显示的页面内容。

手动再现一下之前的场景,下图为综合过程结果:
综合过程

  • ajax请求,发送/findList查询到后台服务端
$.ajax({
    url:serverUrl+'/departments/findList',
    type:'post',
    data: row,
    async:false,
    success: function (data) {
        if (data.success) {
            $.messager.alert("错误");
  • 接着服务端拦截器处理请求,博主使用的shiro管理会话和权限,所以会拦截请求做对应的的校验,若校验失败(本例以session失效演示),则进入filter设置好的重定向目录/sessionFailure
    shiro过滤器设置

  • 由于session失效或权限不足等情况引起的框架(或用户自己使用redirect之类的跳转)重定向,会直接在ServletResponse里设置head的location值,告诉前端请求,向这个新地址重新请求,那么之前请求的/findList,压根就没有到具体业务运行的代码上就已经去执行新的请求了/sessionFailure,如最开始的第一张过程图

  • 之后我们在请求/sessionFailure中做对应业务处理,有2种返回方式:页面返回和json返回。从现在的开发来看,如果使用的页面返回,那么是适用于伪前后端分离和不分离的项目架构,这里只需要使用脚本语言即可,会自动帮你处理好response的页面展示;

  • 从前后端分离式开发看,服务端是不做页面返回的,所以统一以json返回,前端自行处理返回的状态,根据状态自行处理静态页面的跳转,但现在前端大多都采用框架结构了,并且前端语言和库更加丰富,实际上前端也在做mvc、mvv开发,具体使用什么语言博主不做说明(因为只会vue2),博主做这个文章是建立在纯静态html+jquery的前端上实现的,也就是说会用ajax+jquery做到全局处理的事情
* 会话过期 -- 用户处于未登录状态 * @param response @RequestMapping("/sessionFailure") public ModelAndView sessionFailure(HttpSession session, HttpServletResponse response) { System.out.println(SecurityUtils.getSubject().getSession().getAttribute(SessionStatus.STATUS)); if (null == getCurrentUser()) { response.setHeader(SessionStatus.STATUS, SessionStatus.EXPIRED); //方法1:返回页面内容跳转 ModelAndView model = new ModelAndView(); model.addObject("result", Result.result(1, false, StatusCode.LOGINOUT, ResultType.LOGINOUT)); //model.setViewName("forward:/user/login.html"); model.setViewName("redirect:/user/login.html"); //方法2:ajax-json返回,由前端捕获自行操作代码 Map<String, Object> result = new HashMap<String, Object>(); result.put("sessionStatus", "expired"); result.put("message", ResultType.LOGINOUT); result.put("code", StatusCode.LOGINOUT); //方法2包装 doResult(response, flag, StatusCode.DEFAULT, null, flag ? "通过" : "失败"); return model;
  • 如果你使用的是跟博主类似的环境,并且是前后端分离式开发,那么建议使用上述的方法2,自己包装返回json,不要返回页面。创建一个js,加入如下引用,在index页面引入一下
$.ajaxSetup({ 
    asycn: false,
    xhrFields: {
        withCredentials: true
    error: function (XMLHttpRequest, textStatus, errorThrown){
        if(XMLHttpRequest.status==403){
            alert('您没有权限访问此资源或进行此操作');
            return false;
    contentType:"application/x-www-form-urlencoded;charset=utf-8",
    complete: function (XMLHttpRequest,textStatus) {
        debugger;
        //通过XMLHttpRequest取得响应头,sessionstatus
        var sessionstatus = XMLHttpRequest.getResponseHeader("sessionStatus"); 
        //通过XMLHttpRequest取得返回的json
        var json = XMLHttpRequest.responseJSON;
        //通过XMLHttpRequest取得返回的text
        var text = XMLHttpRequest.responseText;
  • 不懂ajaxSetup可以看一下,ajaxSetup是一个类似前端ajax父级的东西,也就是说如果有了这个,你的页面里写的其他$.ajax就是它的子集,会默认带上ajaxSetup上设置的属性,另外ajaxSetup的一些方法如dataFilter、complete、success都是
    在你的ajax请求时会去执行的方法(至于先执行还是后执行,不是本文讨论的方法,后续做详细介绍)。

  • 这里博主是利用的complete监听所有的ajax请求,在请求执行完成后进入方法,执行后续动作,若服务端在重定向执行我上述的/sessionFailure请求时返回了json,那么就使用XMLHttpRequest.responseText去读取服务端返回的json内容,判断你返回的状态,上面代码服务端的例子是用的sessionStatus,所以现在前端例子上也是用这个办法,博主列举了可行的三种方式,任选。

有问题留言交流,博主比较懒,草稿箱里有四十多篇没写完的博客,只能趁现在工作不忙,一段时间一篇慢慢还原环境去补充了,累!!!!

阅读目录问题描述原因解析解决方法携带参数进行重定向RedirectAttributes的使用使用RedirectAttributes携带参数进行重定向例子小疑惑 问题描述 前端的form表单提交,Ajax发送了一个post请求,后端控制器方法处理后,进行页面跳转时,发现无法进行自动跳转。 前端代码: <form action="" method="post" id="form1"> <!-- 此处省略form表单中的内容--> <button id="regbtn" t 我有我想查询外部服务器上的数据库。 要做到这一点,我将我的本地服务器(Tomcat)的上创建一个AJAX调用(只是XMLHttpRequest对象 - 我没有使用任何JavaScript库)页面标有查询。 粘贴完全相同的网址到Firefox使其尝试下载一个XML文档。 我的目标是使用AJAX来获取XML文档。我遇到的问题是,当我做与AJAX调用,萤火虫表明GET响应返回302“暂时移动”用一... 比如说浏览器打开了一个单页面(SPA)应用,过了一段时间token(或者session)过期了,这个时候页面上发起 Ajax请求之后,后端返回302状态码跳转到login页面。 我这是使用的是 Vue + axios ,发现 axios 无法拦截到 302请求,下面是处理的过程。思考google axios 302 handle 看到 axios github 上的两个讨论• https://g... 原文地址: http://blog.csdn.net/u013997090/article/details/77338508?locationNum=8&fps=1最近写的一个servlet过滤器,用于拦截请求,判断用户是否登录。写好后发现一个问题,当我直接在浏览器地址栏里输入地址,可以跳转页面;当点击按钮时,过滤器代码正常执行,但是页面没有跳转;是因为按钮都是ajax请求,默认ajax是不支持重 微软正有条不紊地推进 Edge 迁移工作。首先自 Edge 85 开始,微软整合了 IE 模式,以便于用户兼容使用;对外正式公布了 IE 和经典版 Edge 的停止支持时间表,而现在当用户使用 IE 11 访问某些不兼容的网站时自动重定向到 Edge 浏览器上。为了迫使用户使用基于 Chromium 的新版 Edge 浏览器,让企业和用户知道在新版 Edge 同样可以访问那些经典版 Edge 和 ... 1.问题当cas登录失败之后如果继续执行ajax请求会报 302 重定向错误,但是因为是ajax请求,所以浏览器不会自动跳转,需要做处理。 1.自己重写ajax方法:不推荐 var Ajax = function() { var that = this; // 创建异步请求对象方法 that.createXHR = function() { if (wind... 1.什么是状态码301,302 301 Moved Permanently(永久重定向) 被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。比如百度百科:http://baike.baidu.com/fenlei/%E6%94%BF%E6%B2%BB%E4%BA%BA%E7%89%A9 解决(一) 1.在Request中将scrapy的dont... 1.前端ajax请求需要cas验证的接口,cas判断未登录,返回302,并在location中返回登录页面地址。5.拦截到这一步之后,js里面直接通过location.href的方式再请求一个需要cas验证的接口。6.这个时候服务器又会返回302跳转的登录页面,由于这一次是直接通过改变浏览器url的方式,4.这个时候,因为js会通过ajax的方式把页面html全拉起来,前端就有了一次处理机会,3.前端js会通过ajax的get请求把location中的页面string全拉下来。 本问题已经有最佳答案,请猛点这里访问。我有一个用ASP.NET MVC编写的后端服务器,使用窗体身份验证。当用户未通过身份验证时,服务器将自动发送302重定向到登录操作并返回登录页。在客户端,我有一个项目列表。只有经过身份验证的用户才能访问此列表。在页面上,我有一个按钮可以使用ajax(jquery的$ajax函数)刷新列表。现在,我的问题是当身份验证票证超时并且用户单击刷新按钮时:我的函数发送一... 背景 Access to XMLHttpRequest at 'http://a.com/api' from origin 'http://b.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed f... I have an axios interceptors and when a user gets forced logged out(because of expired token) I want to go back to my home page.I am not sure how to pass react router to it though. I am using mobx but... 今天使用ssh编写OA项目的时候,在写列表展示用户数据的的时候,在写到修改用户数据的时候,修改完数据点击提交的时候,数据可以进行修改,但是页面无法重定向到列表展示页面,在网上查找了很多资料,有的说是要改struts2的改版本将2.5的改成2.3的版本,但是我的项目中是配合maven开发的,所以更改起来会有好多问题,有的人也说删掉某一个包,具体是什么忘了,但是我查找了我自己的包,并没有导入这个包,最