如何使用Axios正确解析传递JSON对象数组类型请求参数
Axios GET请求序列化对象数组参数返回[object Object]问题解决
问题场景
使用Axios发起GET请求时,需要将包含对象数组的JSON结构作为params传递给接口,自定义参数序列化逻辑后,数组内的对象被错误转换为[object Object],接口返回500错误。
待传递参数结构
const annotations = { "key": "Book.pdf", "pages": [ { "start": "12", "end": "20" }, { "start": "35", "end": "40" } ] }
原有请求代码
try { const result = await axios.get(endpoint, { params: annotations, paramsSerializer: params => parseParams(params), headers: { 'Authorization': 'Bearer ' + jwtToken, 'Content-Type': 'application/json' }, 'withCredentials': true }); } catch (error) { console.log(error); }
原有自定义序列化函数
const parseParams = (params) => { const keys = Object.keys(params); let options = ''; keys.forEach((key) => { const isParamTypeObject = typeof params[key] === 'object'; const isParamTypeArray = isParamTypeObject && (params[key].length >= 0); if (!isParamTypeObject) { options += `${key}=${params[key]}&`; } if (isParamTypeObject && isParamTypeArray) { params[key].forEach((element) => { options += `${key}=${element}&`; }); } }); return options ? options.slice(0, -1) : options; };
错误表现
最终拼接出的错误URL如下,数组内的对象被JS默认toString()逻辑转成了[object Object]:
https://api.mysite.com/ConvertBook?key=Book.pdf®ions=[object%20Object]®ions=[object%20Object]
根本原因
原有序列化逻辑仅覆盖了基础类型值、数组元素为基础类型的场景,没有处理数组元素为嵌套对象的情况:直接将对象拼接到字符串时,JS会默认调用对象的toString()方法,最终输出[object Object]。
解决方案
根据后端接口的参数解析规则,可选择以下两种实现方案:
方案1:使用QS库序列化(推荐,兼容绝大多数后端框架)
Axios本身内置依赖qs库,无需额外安装,直接引入即可支持嵌套对象、数组的多规则序列化:
// 引入Axios自带的qs依赖 import qs from 'qs'; // 修改请求配置中的paramsSerializer try { const result = await axios.get(endpoint, { params: annotations, paramsSerializer: params => qs.stringify(params, { arrayFormat: 'indices', // 生成带索引的数组格式,如pages[0][start]=12,适配SpringBoot、Django等多数主流框架 // 其他可选arrayFormat配置: // brackets: 生成不带索引的数组格式,如pages[][start]=12 // repeat: 生成重复键名格式,如pages=xxx&pages=yyy encode: true // 自动完成URL编码 }), headers: { 'Authorization': 'Bearer ' + jwtToken }, withCredentials: true }); } catch (error) { console.log(error); }
序列化后生成的正确URL示例:
https://api.mysite.com/ConvertBook?key=Book.pdf&pages[0][start]=12&pages[0][end]=20&pages[1][start]=35&pages[1][end]=40
方案2:修复自定义序列化函数
如果不想依赖QS,可补全原有函数的递归处理逻辑,支持嵌套对象/数组的序列化,修复后的代码如下:
const parseParams = (params, parentKey = '') => { const paramSegments = []; // 处理基础类型值 if (['string', 'number', 'boolean'].includes(typeof params) || params === null || params === undefined) { return `${encodeURIComponent(parentKey)}=${encodeURIComponent(params ?? '')}`; } // 处理数组结构 if (Array.isArray(params)) { params.forEach((item, index) => { const currentKey = `${parentKey}[${index}]`; paramSegments.push(parseParams(item, currentKey)); }); return paramSegments.join('&'); } // 处理普通对象结构 Object.keys(params).forEach(key => { const currentKey = parentKey ? `${parentKey}[${key}]` : key; paramSegments.push(parseParams(params[key], currentKey)); }); return paramSegments.join('&'); };
注意事项
- GET请求没有请求体,配置
Content-Type: application/json对GET请求无效,可以移除该请求头。 - 不同后端框架对URL嵌套参数的解析规则存在差异,需提前和后端确认接收格式再调整序列化规则:部分框架要求数组参数不带索引,部分框架要求直接将JSON字符串作为单个参数值传递(该场景直接对嵌套结构执行
JSON.stringify()后传值即可)。 - 若接口支持POST请求,复杂嵌套参数优先放在POST请求体中传递,既可以避免URL参数序列化的兼容问题,也不受URL长度限制。
内容的提问来源于stack exchange,提问作者NineCattoRules
相关产品推荐
相关产品推荐

