使用axios发送moment.js对象到服务端返回400错误该如何解决?
问题解决方法
根因分析
400错误核心为请求参数序列化异常:
- 直接传入
moment实例而非原始字符串/时间戳时,axios默认JSON序列化逻辑对非原生JS对象的处理不符合预期 - 另一常见诱因是请求逻辑/拦截器中存在重复JSON序列化操作:第一次序列化得到带引号的时间字符串,第二次序列化时会对该字符串再次转义包裹引号,最终得到
"\"2021-08-31T16:00:00.000Z\""的异常值
解决方法
- 方案1:手动转换moment对象(推荐,最轻量)
发送请求时主动将moment实例转为后端需要的时间格式,避免直接传递moment对象:axios.post('/apiUrl', { // 转ISO标准时间格式,和报错里的时间格式匹配 startTime: moment('2021-9-1').toISOString() // 如果后端需要指定格式比如年-月-日,用format方法 // startTime: moment('2021-9-1').format('YYYY-MM-DD') }) - 方案2:全局配置axios自动处理moment对象(适合项目内频繁传moment参数的场景)
修改axios全局配置的transformRequest,增加moment类型的自动转换逻辑:axios.defaults.transformRequest = [ function (data) { // 遍历参数,moment类型自动转ISO字符串 if (data && typeof data === 'object') { Object.keys(data).forEach(key => { if (moment.isMoment(data[key])) { data[key] = data[key].toISOString() } }) } return JSON.stringify(data) } ] - 方案3:排查重复序列化逻辑
检查全局请求拦截器、自定义请求封装逻辑,是否存在手动调用JSON.stringify()处理请求参数后,又交给axios默认序列化的重复操作,删除多余的序列化步骤即可。
验证方式
修改后打开浏览器开发者工具的「网络」面板,查看对应请求的Payload,确认startTime的值为不带外层额外引号的标准时间格式即可。
内容的提问来源于stack exchange,提问作者robo
相关产品推荐
相关产品推荐

