针对ajax请求时拦截器不跳转问题

博主在开发中,将原本用js控制的页面跳转改为ajax异步请求后,发现拦截器不再拦截请求和跳转页面。经梳理,因ajax是异步请求,仅走回调函数处理后台数据。给出解决办法,用$.ajaxSetup()在请求完成后判断session状态,超时则跳转页面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言(下面有博主符合自身案例的解决方法)


在有一次开发中,原本用的是js控制页面跳转,控制器来接收并对此请求进行拦截。

之后js模块需要增加逻辑代码,特殊要求,所以改成了ajax进行异步请求。

最后发现用ajax请求的地址在处理后拦截器并不拦截此请求,也不会进行跳转(ps:当然不会跳转了),这让我一直感觉我的拦截器地址配置写错了,进行一番查阅后,这里对这个问题进行了一些梳理

解释


ajax为异步请求,前台的逻辑最后都走ajax的回调函数,也仅走回调函数,也就是success。

只会接收后台传送过来的数据,不会对页面跳转拦截这样的请求进行处理。

解决办法


以下是经过搜索后整理的办法

使用$.ajaxSetup(),也可以理解为对ajax的增强,它会在每个ajax请求后得到执行。

// 解决Ajax异步请求 springMvc 不跳转页面的问题
$.ajaxSetup( {
	//设置ajax请求结束后的执行动作
    complete :
        function(XMLHttpRequest, textStatus) {
			// 通过XMLHttpRequest取得响应头,sessionstatus
            var sessionstatus = XMLHttpRequest.getResponseHeader("sessionstatus");
            if (sessionstatus == "TIMEOUT") {
                var win = window;
                while (win != win.top){
                    win = win.top;
                }
                win.location.href= XMLHttpRequest.getResponseHeader("CONTEXTPATH");
            }
        }
});

这段代码的含义,大抵就是,在 ajax请求完成以后,执行 complete 回调方法,里面进行一些逻辑的判断;

这里判断 session 的状态,如果是超时被销毁了,则进行页面的跳转,跳到 CONTEXTPATH 的值那 ;

session 的状态以及 CONTEXTPATH 的值,由我们后台同学定义;

如下:在拦截器的preHandle方法中,添加如下逻辑
 

HttpSession session = httpServletRequest.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            // 获取到项目名,以便下面进行重定向
            String homeUrl = httpServletRequest.getContextPath();
         	// 如果是 ajax 请求,则设置 session 状态 、CONTEXTPATH 的路径值
         	// 如果是ajax请求响应头会有,x-requested-with
            if (httpServletRequest.getHeader("x-requested-with") != null && httpServletRequest.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){
                httpServletResponse.setHeader("SESSIONSTATUS", "TIMEOUT");
                httpServletResponse.setHeader("CONTEXTPATH", homeUrl+"/index.html");
                // FORBIDDEN,forbidden。也就是禁止、403
                httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN); 
            }else{
                // 如果不是 ajax 请求,则直接跳转即可
                httpServletResponse.sendRedirect(homeUrl+"/index.html");
            }
            return false;
        }

 

附:什么是回调函数


ajax提交了一个action或do的请求,这个时候ajax是向后台请求了数据,然后后台也给了对应的数据,后台做好了该怎么给前台,这时候就有了ajax的回调函数。

回调函数是在ajax里面定义的,当请求并完成了对数据的请求时,就调用了ajax的success回调函数,把数据给ajax,然后success通过回调函数来处理这些数据

本次只针对遇到的问题进行笔记共享,如有不对或者补充的,欢迎指正。

<think>好的,用户遇到了Axios拦截器中添加Authorization请求头无效的问题。我需要根据提供的引用资料来找出可能的原因和解决方案。首先,引用[2]中提到,第二次请求请求头中的token失效,可能是因为在拦截器中设置的headers被后续的请求配置覆盖了。解决方案是在拦截器中合并headers,而是直接替换。引用[3]和[4]也提到在拦截器中正确设置headers的方法,比如从localStorage获取token并添加到config.headers.Authorization。此外,引用[4]还提到设置baseURL可能会影响请求路径,需要检查是否正确。可能的原因还包括拦截器未正确注册、本地存储中token存在或过期、以及服务端未正确处理跨域请求。需要逐步排查这些可能性,并确保拦截器中的配置正确合并headers,避免被覆盖。同,建议用户在发起请求需要额外添加headers,除非有特殊需求。最后,检查请求路径是否正确,避免因路径错误导致拦截器未生效。</think>### Axios拦截器设置Authorization请求头无效的解决方案 #### 一、问题诊断 1. **headers覆盖问题** 拦截器中直接赋值`config.headers = {authorization}`会导致后续请求覆盖原有headers配置(如Content-Type),应使用对象合并方式: ```javascript config.headers = { ...config.headers, authorization: token } // ES6扩展运算符合并对象[^2] ``` 2. **拦截器注册顺序** 确保拦截器在axios实例创建后立即注册,避免请求发出后才设置拦截器: ```javascript const instance = axios.create() instance.interceptors.request.use(config => { /* 配置处理 */ }) // 先注册拦截器再发送请求[^3] ``` 3. **本地存储状态异常** 检查token是否存在或过期,建议添加容错处理: ```javascript const token = localStorage.getItem('token') || sessionStorage.getItem('token') if (!token) router.push('/login') // 无token跳转登录页[^4] ``` #### 二、标准解决方案 ```javascript // axios全局配置(推荐封装为独立模块) axios.defaults.baseURL = 'http://api.example.com' // 设置统一基地址[^4] // 请求拦截器 axios.interceptors.request.use(config => { const token = localStorage.getItem('token') return { ...config, headers: { ...config.headers, // 保留原有headers Authorization: token ? `Bearer ${token}` : '' // 标准JWT格式 } } }, error => Promise.reject(error)) ``` #### 三、特殊场景处理 1. **多axios实例冲突** 为同API服务创建独立实例: ```javascript const authAPI = axios.create({ baseURL: '/auth' }) authAPI.interceptors.request.use(/* 专属拦截器 */) ``` 2. **文件上传请求头** FormData类型请求需保留Content-Type: ```javascript if (config.data instanceof FormData) { config.headers['Content-Type'] = 'multipart/form-data' } ``` 3. **服务端CORS配置** 确保服务端允许Authorization头: ```nginx add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type'; ``` #### 四、验证流程 1. 浏览器开发者工具查看Network选项卡 2. 检查请求头是否包含`Authorization: Bearer <token>` 3. 使用测试接口验证401状态码处理逻辑
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值