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

如何通过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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 08:10:28