如何通过Redux-Toolkit (RTK) Query动态设置可选请求头?
问题:RTK Query动态切换Content-Type请求头
使用Redux-Toolkit (RTK) Query构建API调用时,默认请求头为'Content-type: application/json',需要实现动态传入参数,在特定请求中将该头修改为'Content-type: text/csv',且不改动请求其他内容。
现有基础API代码:
export const baseApi = createApi({ refetchOnFocus: true, baseQuery: retry( fetchBaseQuery({ baseUrl: API_BASE_URL, prepareHeaders: async (headers) => { const token = await getAuth0KeyAccessToken(); if (!token) { console.warn('Token not set'); } headers.set('Authorization', `Bearer ${token}`); if (isCsv) { // <-- `isCsv`未定义,需传入该参数 headers.set('Content-Type', 'text/csv'); } return headers; }, }), { maxRetries: 2 }, ), tagTypes: ['Reporting'], endpoints: () => ({}), });
调用基础API的代码:
getCSV: builder.query<any, IReportingQuery>({ providesTags: ['Reporting'], transformResponse: (response: { data: ReportingDP[] | ReportingDP }, meta, arg) => arg.group_by ? response.data : Array.isArray(response.data) ? response.data.sort(dayComparator) : [response.data], query: (body) => ({ url: '/api/v3/reporting', method: 'POST', body }), }),
解决方案
步骤1:修改Endpoint的参数与Query配置
调整getCSV接口的参数结构,将isCsv标记与请求体一起传入,并在query返回对象中添加meta字段存储该标记:
// 调整参数类型为包含body和isCsv的对象 getCSV: builder.query<any, { body: IReportingQuery; isCsv: boolean }>({ providesTags: ['Reporting'], transformResponse: (response: { data: ReportingDP[] | ReportingDP }, meta, arg) => arg.body.group_by ? response.data : Array.isArray(response.data) ? response.data.sort(dayComparator) : [response.data], query: ({ body, isCsv }) => ({ url: '/api/v3/reporting', method: 'POST', body, meta: { isCsv } // 将isCsv标记存入meta }), }),
步骤2:包装BaseQuery以传递isCsv参数
通过包装原fetchBaseQuery,获取每个请求的meta中的isCsv值,再传入prepareHeaders中处理:
export const baseApi = createApi({ refetchOnFocus: true, baseQuery: retry( async (args, api, extraOptions) => { // 从请求参数的meta中提取isCsv标记,默认false const isCsv = typeof args === 'object' && args.meta?.isCsv ?? false; // 调用原fetchBaseQuery,传入自定义的prepareHeaders const result = await fetchBaseQuery({ baseUrl: API_BASE_URL, prepareHeaders: async (headers) => { const token = await getAuth0KeyAccessToken(); if (!token) { console.warn('Token not set'); } headers.set('Authorization', `Bearer ${token}`); // 根据isCsv动态设置Content-Type if (isCsv) { headers.set('Content-Type', 'text/csv'); } else { // 确保默认请求头为application/json headers.set('Content-Type', 'application/json'); } return headers; }, })(args, api, extraOptions); return result; }, { maxRetries: 2 } ), tagTypes: ['Reporting'], endpoints: () => ({}), });
步骤3:调用接口时传入isCsv参数
使用getCSV时,传入包含请求体和isCsv标记的对象即可:
// 需要CSV格式时 dispatch(getCSV.initiate({ body: yourQueryParams, isCsv: true })); // 默认JSON格式时 dispatch(getCSV.initiate({ body: yourQueryParams, isCsv: false }));
内容的提问来源于stack exchange,提问作者Devstar34
相关产品推荐
相关产品推荐

