React中RTK Query结合Axios无法传递Bearer Token的问题
问题解决思路
你的核心问题是自定义的axios baseQuery没有集成RTKQ的状态访问能力和prepareHeaders逻辑,同时store配置中缺少了bulkApplyApi的中间件,导致无法获取token并添加到请求头中。以下是具体修复步骤:
1. 修复自定义axiosBaseQuery函数
调整baseQuery的结构,使其支持接收prepareHeaders参数,并能通过RTKQ提供的getState工具访问store中的token:
import { createApi } from "@reduxjs/toolkit/query/react"; import axios from "axios"; import TIDEAPI from "./api.json"; const BASE_URL = TIDEAPI.BASEURL; const axiosBaseQuery = ({ baseUrl, prepareHeaders } = { baseUrl: "" }) => // 接收RTKQ提供的第二个参数,包含getState工具 async ({ url, method, data, params }, { getState }) => { let headers = new Headers(); // 调用传入的prepareHeaders处理请求头 if (prepareHeaders) { headers = prepareHeaders(headers, { getState }); } // 将Headers实例转换为axios可识别的普通对象 const axiosHeaders = Object.fromEntries(headers.entries()); try { const result = await axios({ url: baseUrl + url, method, data, params, headers: axiosHeaders, // 可选:添加上传进度监听(你需要的功能) // onUploadProgress: (progressEvent) => { // const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total); // console.log(`上传进度:${percent}%`); // } }); return { data: result.data, params: result.params }; } catch (axiosError) { const err = axiosError; return { error: { status: err.response?.status, data: err.response?.data || err.message, }, }; } }; export const bulkApplyApi = createApi({ reducerPath: "bulkApplyApi", baseQuery: axiosBaseQuery({ baseUrl: BASE_URL, // 调整prepareHeaders的参数结构,使用getState获取store状态 prepareHeaders: (headers, { getState }) => { const { token } = getState().authentication; if (token) { headers.set("authorization", `Bearer ${token}`); } return headers; }, }), endpoints: (builder) => ({ upload: builder.mutation({ query: ({ id, data }) => ({ url: `/API/path?id=${id}`, method: "put", data, }), }), }), }); export default bulkApplyApi; export const { useUploadMutation } = bulkApplyApi;
2. 完善Store配置
在middleware中添加bulkApplyApi.middleware,确保RTKQ的内部逻辑(包括状态访问)正常运行:
import { configureStore } from "@reduxjs/toolkit"; import { reducer as searchReducer, searchSlice, } from "components/search/reducer"; import { api } from "services"; import { bulkApplyApi } from "services/bulkApplyApi"; import authenticationReducer from "./authentication/authSlice"; export const store = configureStore({ reducer: { [api.reducerPath]: api.reducer, [bulkApplyApi.reducerPath]: bulkApplyApi.reducer, [searchSlice.name]: searchReducer, authentication: authenticationReducer, }, middleware: (getDefaultMiddleware) => // 添加bulkApplyApi的中间件 getDefaultMiddleware().concat(api.middleware, bulkApplyApi.middleware), });
关键修改说明
- 状态访问:通过RTKQ传入的
getState工具获取store中的token,而不是直接访问store实例 - 请求头处理:在axios请求前调用
prepareHeaders生成最终请求头,并转换为axios支持的格式 - 中间件补充:每个RTKQ的
createApi实例都需要添加对应的middleware,否则无法正常处理缓存、状态同步等逻辑
内容的提问来源于stack exchange,提问作者Kris Renaldi
相关产品推荐
相关产品推荐

