解决Ajax请求后端重定向失效问题

作者:服务小站

时间:2026-10-23

浏览:535

本文详细解析了Ajax异步请求中后端重定向失效的原因,并提供了一套完整的解决方案。通过后端设置自定义响应头标识重定向意图,前端利用jQuery的ajaxComplete全局钩子统一处理跳转逻辑,既解决了Token过期跳转登录页的需求,又实现了代码的高复用性。

文章目录

Ajax重定向问题背景

前言

在实际开发中常遇到一种现象:通过Ajax发起请求时,若后端执行重定向操作,前端无法像普通浏览器访问那样自动跳转至新页面,只有在地址栏直接输入URL时重定向才生效。

这是因为Ajax机制设计为局部刷新,旨在不重新加载整个页面的情况下与服务器交换数据,因此它默认不支持传统的页面重定向行为。

后端网关Token拦截处理

本文旨在解决一个典型场景:后端网关需检查请求中是否包含有效的Token,若缺失则引导用户至登录页面。由于绝大多数交互均基于Ajax,直接重定向会导致请求落入Ajax的错误处理或成功回调中,而非页面跳转。为此,需前后端协同处理,具体方案如下。

后端实现逻辑如下:


/**
*功能描述
* @author lgj
* @Description 重定向工具类
* @date 2/27/19
*/
@Slf4j
public class RedirecUtil {
/**
*功能描述
* @author lgj
* @Description 重定向
* @date 2/27/19
* @param:
* @return:
*
*/
public static void redirect(RequestContext ctx, String redirectUrl){
try{
//如果是Ajax请求
if("XMLHttpRequest".equals(ctx.getRequest().getHeader("X-Requested-With"))){
log.debug("ajax redirect");
sendRedirect(ctx.getResponse(),redirectUrl);
}
//如果是浏览器地址栏请求
else {
log.debug("normal redirect ");
ctx.getResponse().sendRedirect(redirectUrl);
}
}
catch(Exception ex){
ex.printStackTrace();
}
}
/**
*功能描述 
* @author lgj
* @Description Ajax请求时重定向处理
* @date 2/27/19
* @param: 
* @return: 
*
*/
private static void sendRedirect(HttpServletResponse response, String redirectUrl){
try {
       //这里并不是设置跳转页面,而是将重定向的地址发给前端,让前端执行重定向
//设置跳转地址
response.setHeader("redirectUrl", redirectUrl);
//设置跳转使能
response.setHeader("enableRedirect","true");
response.flushBuffer();
} catch (IOException ex) {
log.error("Could not redirect to: " + redirectUrl, ex);
}
}
}

前端重定向解决方案

前端需配合后端进行相应处理,主要有两种实现路径。

第一种方案是利用Ajax配置中的complete回调函数。


$.ajax({
type: "post",
url: "/auth/token/check",
success: function(data,status){
console.log("/token/check 返回 status : "+status)
},
//请求完成调用
(XHR, TS){
console.log("complete");
var url = XHR.getResponseHeader("redirectUrl");
console.log("redirectUrl = " + url);
var enable = XHR.getResponseHeader("enaleRedirect");
console.log("enableRedirect = " + enable);
if((enable == "true") && (url != "")){ 
var win = window; 
         while(win != win.top){
      win = win.top;
        }
         win.location.href = url; 
          } 
      }, 
    });
})

然而,该方案存在明显缺陷:每个独立的Ajax请求都必须单独编写complete逻辑,导致代码冗余且复用率极低。

第二种方案更为推荐:利用jQuery提供的全局ajaxComplete事件进行统一处理。

具体而言,在发起Ajax请求时,需确保请求正常发送。


$("#NON-TOKEN").click(function () {
$.ajax({
type: "post",
url: "/auth/token/check",
success: function(data,status){
console.log("/token/check 返回 status : "+status)
},
});

同时,在全局层面注册ajaxComplete监听器,以便在所有Ajax请求完成后执行统一的重定向检查逻辑。

需要注意的是,全局监听器的回调函数必须严格保留event、xhr和settings三个参数,否则可能引发运行时错误。


//每一个Ajax 请求完成之后都会执行。
$(document).ajaxComplete(function (event, xhr, settings) {
console.log("ajaxComplete ")
redirectHandle(xhr);
})

function redirectHandle(xhr) {
  //获取后台返回的参数
var url = xhr.getResponseHeader("redirectUrl");
console.log("redirectUrl = " + url);
var enable = xhr.getResponseHeader("enableRedirect");
if((enable == "true") && (url != "")){
var win = window;
while(win != win.top){
win = win.top;
}
win.location.href = url;
}
}

代码复用与封装建议

为了进一步提升代码复用率,建议将上述前端处理逻辑封装至独立的JS文件中,并在需要执行重定向功能的页面中引入该文件即可。

该独立文件通常命名为redirect.js。


function redirectHandle(xhr) {
var url = xhr.getResponseHeader("redirectUrl");
console.log("redirectUrl = " + url);
var enable = xhr.getResponseHeader("enableRedirect");
if((enable == "true") && (url != "")){
var win = window;
while(win != win.top){
win = win.top;
}
win.location.href = url;
}
}
$(function () {
$(document).ajaxComplete(function (event, xhr, settings) {
console.log("ajaxComplete adffdafadsaf")
redirectHandle(xhr);
})
})

在HTML页面中,通过script标签引入该JS文件,src属性需根据实际部署路径进行调整。


<script src="/common/redirect.js"></script>

以上即为解决Ajax请求中后端重定向失效问题的完整方案,希望能为相关开发工作提供有益参考。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章