如何在组件外通过next-i18next修改axios的Accept-Language请求头?
问题场景
自定义setLanguageHeader函数修改Axios实例的Accept-Language请求头,切换语言后查看serviceWithSessing.defaults.headers.common已更新为目标语言(如jp),但Chrome网络面板中实际请求的Accept-Language仍为初始值zh-TW。
Axios配置文件requests.ts(关键片段)
const serviceWithSessing = axios.create({ timeout, baseURL, withCredentials: true, }); serviceWithSessing.interceptors.request.use( (config: any) => { let customHeaders: any = { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': true, 'Accept-Language': 'zh-TW', // 硬编码固定值 }; config.headers = customHeaders; // 直接覆盖原有headers return config; }, // ...错误处理 ); // 自定义修改语言头的函数 const setLanguageHeader = (language: 'zh' | 'en-US' | 'jp') => { serviceWithSessing.defaults.headers.common['Accept-Language'] = language; };
语言切换调用(_app.tsx)
import { i18n } from 'next-i18next'; import { setLanguageHeader } from '@/api/request'; setLanguageHeader(i18n?.language);
原因分析
请求拦截器中直接替换了config.headers为硬编码的自定义对象,完全覆盖了Axios实例defaults中配置的headers。也就是说,不管你通过setLanguageHeader修改多少次defaults,最终都会被拦截器里的'Accept-Language': 'zh-TW'覆盖,导致实际请求头不更新。
解决方案
修改请求拦截器:合并headers而非覆盖
保留原有config.headers的内容(包括defaults里的配置),再合并自定义的固定headers,避免覆盖defaults中更新的Accept-Language:serviceWithSessing.interceptors.request.use( (config: any) => { // 合并原有headers和自定义固定headers,不硬编码Accept-Language config.headers = { ...config.headers, // 保留原有headers(含defaults配置) 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': true, }; return config; }, error => { console.log('interceptors error', error); return Promise.reject(error); // 必须返回Promise,否则拦截器流程中断 } );优化
setLanguageHeader的类型匹配
由于i18n?.language的返回值可能和后端要求的标识不一致(比如i18n返回'ja'而非'jp'),可以添加语言映射逻辑,确保传入有效值:const setLanguageHeader = (language: string) => { // 语言标识映射表,根据实际需求调整 const langMap: Record<string, string> = { 'ja': 'jp', 'zh-CN': 'zh', 'zh-TW': 'zh-TW', 'en': 'en-US' }; const targetLang = langMap[language] || language; serviceWithSessing.defaults.headers.common['Accept-Language'] = targetLang; };处理
_app.tsx中的可选值i18n?.language可能为undefined,添加判断避免传入无效参数:import { i18n } from 'next-i18next'; import { setLanguageHeader } from '@/api/request'; if (i18n?.language) { setLanguageHeader(i18n.language); }
验证修改
修改后切换语言,调用setLanguageHeader后,查看网络面板的请求头,Accept-Language应该会同步更新为目标语言;同时serviceWithSessing.defaults.headers.common的修改也会正确反映到实际请求中。
内容的提问来源于stack exchange,提问作者Morton

