Axios版本升级后API响应JSON未自动解析问题求助
Axios 0.18.0升级至1.6.2后JSON响应未自动解析问题
问题重现
旧版本(0.18.0)代码及正常行为
创建Axios实例时指定responseType: 'json',响应会自动将JSON字符串解析为对象:
const axiosInstance = axios.create({ responseType: 'json', baseURL: `api/v1/example`, headers: { 'Content-Type': 'application/vnd.api+json', Accept: 'application/vnd.api+json', }, }); axiosInstance.interceptors.response.use((response) => { console.log(response); return response; }, callback);
日志输出:
{ "data": { "foo": "bar" }, // typeof object(自动完成JSON解析) "status": 200, "statusText": "", "headers": {}, "config": { "transformRequest": {}, ... } }
新版本(1.6.2)代码及异常行为
相同配置下,响应的data仍为JSON字符串,未被自动解析:
axiosInstance.interceptors.response.use((response) => { console.log(response); return response; }, callback);
日志输出:
{ "data": "{\"foo\":\"bar\"}", // typeof string(未自动解析JSON) "status": 200, "statusText": "", "headers": {}, "config": { "transformRequest": {}, ... } }
响应头Content-Type为application/vnd.api+json; charset=utf-8。
原因分析
Axios 1.x版本对响应解析逻辑做了核心调整:
- 0.18.0版本中,只要设置了
responseType: 'json',Axios会强制尝试将响应内容解析为JSON,完全忽略响应头的Content-Type类型。 - 1.6.2等1.x版本中,Axios默认解析逻辑优先依据响应头Content-Type判断是否触发JSON解析,仅当Content-Type匹配
application/json或application/*+json时才自动解析。但部分场景下,自定义的application/vnd.api+json可能因配置优先级或规则匹配细节问题,未触发自动解析逻辑。 - 同时1.x版本中
responseType的优先级被下调,不再强制覆盖Content-Type的判断逻辑,需要配合自定义解析规则才能处理非标准JSON类型。
解决方案
方案1:自定义transformResponse强制解析JSON
在创建Axios实例时,手动添加解析逻辑,确保响应内容被转为JSON对象:
const axiosInstance = axios.create({ responseType: 'json', baseURL: `api/v1/example`, headers: { 'Content-Type': 'application/vnd.api+json', Accept: 'application/vnd.api+json', }, transformResponse: [function (data) { try { return JSON.parse(data); } catch (e) { // 解析失败时返回原数据 return data; } }] });
方案2:配置Axios识别自定义Content-Type
通过全局或实例配置,让Axios明确将application/vnd.api+json视为JSON类型:
// 全局配置(对所有Axios实例生效) axios.defaults.headers.common['Accept'] = 'application/vnd.api+json'; axios.defaults.headers.post['Content-Type'] = 'application/vnd.api+json'; // 或者在实例中组合配置 const axiosInstance = axios.create({ baseURL: `api/v1/example`, headers: { 'Content-Type': 'application/vnd.api+json', Accept: 'application/vnd.api+json', }, responseType: 'json', // 继承默认解析逻辑并确保触发 transformResponse: axios.defaults.transformResponse.concat(function(data) { return data; }) });
方案3:在响应拦截器中手动解析
如果不想修改实例基础配置,可在拦截器中针对性处理:
axiosInstance.interceptors.response.use((response) => { // 判断数据类型和响应头,符合条件时手动解析 if (typeof response.data === 'string' && response.headers['content-type']?.includes('application/vnd.api+json')) { try { response.data = JSON.parse(response.data); } catch (e) { // 保留原数据避免异常扩散 } } return response; }, callback);
内容的提问来源于stack exchange,提问作者Josh Doe
相关产品推荐
相关产品推荐

