axios 的 GET 请求里,手动写 Content-Type: application/json 基本都会被删掉不是你写法错了是 axios 源码故意这么做的
一、为什么 GET 的 Content-Type 会被删掉
看 axios 源码(xhr.js)里的逻辑:
if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') { // Remove Content-Type if data is undefined delete requestHeaders[key]; }- GET 请求默认没有
data→requestData === undefined - 只要是 GET,你在 headers 里写的 Content-Type 会被直接删掉
- HTTP 规范本来也规定:Content-Type 是描述请求体的,GET 不该有 body
所以下面这种写法永远不生效:
// ❌ 无效 axios.get('/api', { headers: { 'Content-Type': 'application/json' }, params: { ... } })二、如果后端强行要这个头,怎么绕过
方案 1:请求拦截器里强行塞一个空 data(推荐)
axios.interceptors.request.use(config => { // 让 GET 也有 data,axios 就不会删 Content-Type if (config.method === 'get' && config.data === undefined) { config.data = null; // 或 {}、true 都行 } // 再统一设置 config.headers['Content-Type'] = 'application/json'; return config; });之后正常写 get 即可:
axios.get('/api', { params: { ... } })这时抓包会看到:
- 有
Content-Type: application/json - 不会真带 body,只是骗过 axios 的判断
方案 2:用 POST 伪装 GET(接口允许的话)
axios.post('/api', {}, { headers: { 'Content-Type': 'application/json' }, params: { ... } })方案 3:全局默认头(配合拦截器)
axios.defaults.headers.common['Content-Type'] = 'application/json';再配合上面拦截器给 GET 塞个 data,就能全局生效。
三、要不要这么做?
- 正常 RESTful 接口:不需要。GET 就不该有 Content-Type,后端设计不合理。
- 老旧 / 第三方接口:没办法,只能用上面拦截器的方式硬塞。
简单总结:axios 会自动删除 GET 请求的 Content-Type,因为 GET 无 body。要强行保留,就在请求拦截器里给 GET 塞一个 data(null/{}),再统一设置 Content-Type 即可。
