You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular中如何通过拦截器在Token过期时取消HTTP请求

解决方案:Token过期时拦截并取消请求

一、你的思路没问题

在请求发送前通过拦截器校验Token有效性,提前拦截无效请求,比等后端返回401再处理更高效,能减少冗余网络请求,这个方向是完全正确的。

二、如何在拦截器中取消请求

不同HTTP客户端的实现方式不同,下面是主流场景的代码示例:

前端Axios场景

在请求拦截器里,检测到Token过期后,返回一个被取消的Promise,Axios会直接终止请求发送:

import axios from 'axios';

// 用CancelToken取消请求(Axios旧版本兼容方案)
axios.interceptors.request.use(config => {
  // 替换成你的Token过期校验逻辑
  const isTokenExpired = Date.now() > localStorage.getItem('tokenExpireTime');
  
  if (isTokenExpired) {
    // 跳转登录页
    window.location.href = '/login';
    // 生成取消令牌并终止请求
    const cancelToken = axios.CancelToken.source();
    cancelToken.cancel('Token已过期,请求被拦截');
    return Promise.reject(cancelToken.token);
  }
  return config;
});

// 用AbortController(Axios v0.22.0+推荐方案)
axios.interceptors.request.use(config => {
  const isTokenExpired = Date.now() > localStorage.getItem('tokenExpireTime');
  
  if (isTokenExpired) {
    window.location.href = '/login';
    const controller = new AbortController();
    config.signal = controller.signal;
    controller.abort('Token过期,请求取消');
    throw new axios.Cancel('请求已拦截');
  }
  return config;
});

Android OkHttp场景

在Interceptor中,Token过期时直接返回一个空响应,同时终止请求链:

class AuthInterceptor(private val context: Context) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        // 替换成你的Token过期校验逻辑
        val isTokenExpired = System.currentTimeMillis() > getTokenExpireTime()
        
        if (isTokenExpired) {
            // 跳转登录页
            val intent = Intent(context, LoginActivity::class.java).apply {
                flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
            }
            context.startActivity(intent)
            
            // 返回空响应,终止请求
            return Response.Builder()
                .request(request)
                .code(401)
                .message("Token Expired")
                .body(ResponseBody.create(null, ""))
                .protocol(Protocol.HTTP_1_1)
                .build()
        }
        return chain.proceed(request)
    }
    
    private fun getTokenExpireTime(): Long {
        // 从本地存储获取Token过期时间
        return 0L
    }
}

三、更优方案参考

  1. Token自动刷新:如果后端提供refreshToken,在拦截器里检测到Token过期时,先调用刷新接口获取新Token,成功后用新Token重新发起原请求,无需跳转登录,用户体验更流畅。注意要加锁避免并发请求重复刷新。
  2. 全局状态前置校验:把Token过期状态存在全局状态管理(比如Vuex、Redux、Android ViewModel),发起请求前先检查状态,不用走到拦截器再处理,简化拦截器逻辑。
  3. 请求队列暂存:Token过期时,把待发送的请求暂存起来,等用户登录成功后再批量重发,适合需要保留用户操作流程的场景。
  4. 前后端协同兜底:前端校验时间可能和服务器有偏差,让后端在返回401时明确标记是Token过期,作为前端逻辑的兜底,避免漏拦截。

内容的提问来源于stack exchange,提问作者Mahesh Dharwad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 02:10:32