无法激活RTK Query中间件:401错误捕获失效问题排查
问题分析
你代码里的核心问题是**createApi没有middleware这个配置项**,所以你写的middleware函数完全不会被执行,自然看不到"middleware activated"的日志,也无法捕获401错误。RTK Query的错误拦截和token刷新逻辑,需要通过自定义baseQuery来实现,而非在createApi里添加无效的配置。
解决方案
移除createApi中的无效middleware配置,改用带重鉴权逻辑的自定义baseQuery,在其中捕获401错误并执行token刷新流程,之后重新发起原请求。
修改后的代码示例
index.js(API配置)
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'; // 假设你有获取、保存、清除token的工具函数,以及退出登录的action import { getToken, saveToken, clearToken } from './tokenUtils'; import { logout } from './user/slice'; // 基础baseQuery const baseQuery = fetchBaseQuery({ baseUrl: '/api/v1', prepareHeaders: (headers) => { const token = getToken(); if (token) { headers.set('Authorization', `Token ${token}`); } return headers; }, }); // 封装带重鉴权的baseQuery const baseQueryWithReauth = async (args, api, extraOptions) => { let result = await baseQuery(args, api, extraOptions); // 捕获401错误 if (result.error && result.error.status === 401) { console.log('检测到401,开始刷新Token'); // 调用刷新Token的接口(根据实际接口路径调整) const refreshResult = await baseQuery( { url: '/auth/refresh', method: 'POST' }, api, extraOptions ); if (refreshResult.data) { // 保存新Token到本地 saveToken(refreshResult.data.newToken); // 重新发起原请求 result = await baseQuery(args, api, extraOptions); console.log('Token刷新成功,原请求已重试'); } else { // 刷新失败,清除本地Token并触发退出登录 clearToken(); api.dispatch(logout()); console.log('Token刷新失败,已退出登录'); } } return result; }; export const bplexApi = createApi({ reducerPath: 'bplexApi', baseQuery: baseQueryWithReauth, // 使用带重鉴权的baseQuery endpoints: () => ({}), });
store配置(无需修改)
你的store配置是正确的,已经正确添加了RTK Query的middleware,保持原样即可:
import { configureStore, getDefaultMiddleware } from "@reduxjs/toolkit"; import userReducer from "./user/slice"; import modelsReducer from "./models/slice"; import { bplexApi } from "../api_v2"; const store = configureStore({ reducer: { user: userReducer, models: modelsReducer, [bplexApi.reducerPath]: bplexApi.reducer, }, middleware: (getDefaultMiddleware) => { return getDefaultMiddleware().concat(bplexApi.middleware); }, }); export default store;
额外说明
- 若需针对单个接口做特殊错误处理,可在
injectEndpoints时使用onQueryStarted钩子捕获错误。 - 刷新Token的接口本身也可能返回401(如refreshToken过期),这种情况需直接触发退出登录逻辑,避免无限循环。
内容的提问来源于stack exchange,提问作者David Abramov
相关产品推荐
相关产品推荐

