Axios formToJSON 遇到 metadata[length] 报数组长度无效
嵌套表单字段名length落到中间数组对象上,可能触发RangeError。按已知字段契约构造JSON,保留重复值和其他表单项的原有含义。
表单只有一个普通字段 metadata[length],调用 axios.formToJSON(form) 却抛出 RangeError: Invalid array length。这个length是业务字段名,不是要求创建一个指定长度的数组。
正式Axios1.20.0的FormData转JSON辅助逻辑,会为尚未建立的嵌套路径先创建数组,递归处理后才视情况转成对象。遍历到length时,字符串被写进数组的特殊length属性,在转成普通对象之前就可能抛错。
字段写法改变不了同一条路径
metadata.length也会被解析成嵌套路径,不能只把方括号换成点就认定修复。重复的同名字段、length下面继续嵌套子字段,也要独立核对。
数值字符串碰巧没有抛异常,也不代表结构正确:数组length有自己的语义,不能把一次转换成功当成得到 { metadata: { length: ... } } 的证据。
该辅助逻辑还用于把FormData作为JSON发送的转换分支。因此,既要检查直接的formToJSON调用,也要检查带Content-Type: application/json的表单请求。它不是单纯的HTTP适配器或网络错误。
JSON接口可以显式构造已知结构
若接口确实接收JSON,且这个字段按契约为字符串,可以在固定表单到请求对象的映射层建立普通对象:
const length = form.get('metadata[length]');
if (typeof length !== 'string') {
throw new TypeError('metadata[length] must be a string');
}
const payload = { metadata: { length } };
这里的form来自应用既有FormData。payload只展示受影响字段,发送真实请求时必须按原schema映射其他必要字段、认证与选项。若字段实际上要求数字,应在该入口按明确格式和范围校验,不能只用Number转换后忽略失败。
form.get只取第一项;原来允许重复值时,要通过getAll按接口规则保留,不能静默丢掉后续项。也不要改用Object.fromEntries再声称恢复嵌套JSON:它会保留平面的带括号键,并且对重复键采用另一种行为。
如果后端原本接收multipart,可以继续发送原FormData,避免为了JSON强行触发这次转换;但后端只接受JSON时,换Content-Type不是等价方案。协议两端应保持一致。
不对不可信路径编写无边界的通用展开器
这个问题不应靠全局删除length字段,或把用户提供的每段键名递归写进任意对象来修。固定字段按schema显式映射更容易核对。需要通用转换时,应采用经过审查、明确处理特殊属性、重复值、数组和深度限制的实现。
已核对的正式1.20.0仍是先创建中间数组再递归,没有已核证的正式修复版本。验收应覆盖length字符串、数字契约、重复值、空字段、NULL或文件项,以及正常数字下标;检查最终JSON结构和后端实际读取的值,而不只确认没有RangeError。


