React+Json-server中如何用Axios拦截特定请求的X-Total-Count头
解决方案
核心思路
利用Axios的自定义配置扩展,在不改动agent.ts原有请求封装结构的前提下,通过回调函数将响应头(X-Total-Count)传递到对应slice,实现各资源独立存储总条数状态。
步骤1:扩展Axios请求配置(TypeScript可选但推荐)
在agent.ts中添加自定义配置类型,避免TypeScript类型报错:
import { AxiosRequestConfig, AxiosResponseHeaders } from 'axios'; declare module 'axios' { interface AxiosRequestConfig { // 自定义回调,用于传递响应头 onHeadersReceived?: (headers: AxiosResponseHeaders) => void; } }
步骤2:修改agent.ts的响应拦截器
在全局响应拦截器中触发自定义回调,传递响应头信息,同时保留原有responseBody逻辑:
// agent.ts 现有代码基础上修改响应拦截器 import axios from 'axios'; const responseBody = (response: any) => response.data; axios.interceptors.response.use( (response) => { // 若请求配置中存在自定义回调,传递响应头 response.config.onHeadersReceived?.(response.headers); // 保持原有逻辑,仅返回响应数据 return responseBody(response); }, (error) => { // 保留原有错误处理逻辑 return Promise.reject(error); } ); // 原有requests封装完全不变 export const requests = { get: (url: string, config?: AxiosRequestConfig) => axios.get(url, config).then(responseBody), // post、put等其他请求方法保持原有结构 }; export default { requests };
步骤3:在各slice的异步Thunk中接收响应头
以bookSlice.ts为例,调用agent请求时传入回调,在回调中更新当前slice的总条数状态:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; import agent from '../agent'; // 异步获取书籍列表 export const fetchBooks = createAsyncThunk( 'books/fetchBooks', async ({ page, limit }: { page: number; limit: number }, { dispatch }) => { const books = await agent.requests.get(`/books?_page=${page}&_limit=${limit}`, { // 自定义回调:解析并传递X-Total-Count onHeadersReceived: (headers) => { const totalCount = parseInt(headers['x-total-count'] || '0', 10); dispatch(setBookTotalCount(totalCount)); } }); return books; } ); const bookSlice = createSlice({ name: 'books', initialState: { list: [], totalCount: 0, status: 'idle' }, reducers: { setBookTotalCount: (state, action) => { state.totalCount = action.payload; } }, extraReducers: (builder) => { builder.addCase(fetchBooks.fulfilled, (state, action) => { state.list = action.payload; state.status = 'succeeded'; }); // 可添加pending、rejected状态处理 } }); export const { setBookTotalCount } = bookSlice.actions; export default bookSlice.reducer;
carSlice.ts、drumSlice.ts可复用相同逻辑,仅需替换资源路径、slice名称及action名称即可。
方案优势
- 无侵入式改造:完全保留
agent.ts中responseBody和requests的原有结构,不影响现有业务代码。 - 职责分离:slice仅处理状态更新,Axios请求仍由
agent.ts集中管理,符合代码分层原则。 - 独立存储状态:各资源的
X-Total-Count分别存入对应slice,状态隔离清晰。
内容的提问来源于stack exchange,提问作者Himanshu Sharma
相关产品推荐
相关产品推荐

