RTK Query将REST请求头转为小写的解决办法咨询
保留RTK Query请求头的大小写方案
RTK Query的fetchBaseQuery底层依赖浏览器fetch API,而fetch的Headers对象会自动规范化请求头名称,导致无法保留自定义的大小写格式。要解决这个问题,最直接的方式是自定义baseQuery函数,绕过fetch的自动规范化逻辑,用XMLHttpRequest发送请求——它能严格按照你设置的头名称发送,不会做自动转换。
实现步骤
- 编写自定义baseQuery函数
const customBaseQuery = async (args, api, extraOptions) => { // 解析请求参数 const requestParams = typeof args === 'string' ? { url: args, method: 'GET' } : { method: 'GET', ...args }; const { url, method, body, headers = {} } = requestParams; const fullUrl = `${process.env.REACT_APP_API_URL}${url}`; return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open(method, fullUrl); // 手动设置请求头,完全保留键名的大小写 Object.entries(headers).forEach(([key, value]) => { xhr.setRequestHeader(key, value); }); // 处理成功响应 xhr.onload = () => { const responseData = xhr.responseText ? JSON.parse(xhr.responseText) : null; if (xhr.status >= 200 && xhr.status < 300) { resolve({ data: responseData, status: xhr.status, headers: xhr.getAllResponseHeaders(), }); } else { reject({ status: xhr.status, data: responseData, error: new Error(xhr.statusText || 'Request failed'), }); } }; // 处理网络错误 xhr.onerror = () => { reject({ status: xhr.status, error: new Error('Network error occurred'), }); }; // 发送请求,序列化body(如果有) if (body) { xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(JSON.stringify(body)); } else { xhr.send(); } }); };
- 在createApi中替换为自定义baseQuery
export const BaseApi = createApi({ baseQuery: customBaseQuery, endpoints: () => ({}), });
- 注入端点时正常设置headers即可
const extendedApi = BaseApi.injectEndpoints({ endpoints: (build) => ({ getType: build.query<string[], string>({ query: (param) => ({ url: `/test/${param}/call`, headers: { Authorization: "Bearer token", // 此处的大小写会被原样发送 } }), }), }), overrideExisting: false });
补充说明
- 如果需要支持RTK Query的自动取消请求逻辑,可以在自定义baseQuery中集成
AbortController,通过api.signal监听取消信号。 - 这个方案的核心是用
XMLHttpRequest替代fetch,避开了fetch对请求头的自动规范化处理,刚好适配那些对大小写敏感的特殊后端服务。
内容的提问来源于stack exchange,提问作者Samuele Faedo
相关产品推荐
相关产品推荐

