Fetch API JSON解析异常:嵌套数组长度不符问题求助
Fetch API JSON解析后嵌套数组长度异常排查方案
调用某接口返回包含嵌套数组的JSON结构,
items数组第一个对象的holdings数组实际应为31项,但通过fetch的res.json()解析后仅显示24项;其他对象的holdings数组均正常。API文档、Postman、Chrome网络面板、response.text()返回的数据均正确,说明接口返回无误,问题出在JSON解析或后续数据传递环节。此外,有时解析结果正常,但将JSON对象传递给其他函数后,holdings长度必然从31变为24。
现有Fetch代码
return await fetch( <URL>, { method: 'GET', headers: { 'Content-Type': 'application/json' } } ) .then((res) => { return res.json(); // 改为res.text()可返回正确数据,但无法直接使用 }) .then((resData) => { if(!resData.error) { return resData; } });
正确响应示例(精简版)
{ "data": { "address": "0x22...", "updated_at": "2022-10-15T18:48:07.076779009Z", "next_update_at": "2022-10-15T18:53:07.076779139Z", "quote_currency": "USD", "chain_id": 1, "items": [ { "contract_decimals": 6, "contract_name": "USD Coin", "contract_ticker_symbol": "USDC", "contract_address": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "supports_erc": null, "logo_url": "https://logos.covalenthq.com/tokens/1/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48.png", "holdings": [ { "timestamp": "2022-10-15T00:00:00Z", "quote_rate": 1.000501, "open": { "balance": "127096912", "quote": 127.16059 }, "high": { "balance": "127096912", "quote": 127.16059 }, "low": { "balance": "127096912", "quote": 127.16059 }, "close": { "balance": "127096912", "quote": 127.16059 } } // 省略其余29项(总计31项) ] } ], "pagination": null }, "error": false, "error_message": null, "error_code": null }
排查思路与解决方案
1. 验证手动JSON解析是否存在同样问题
将res.json()替换为手动解析res.text()的内容,确认是否是浏览器原生JSON.parse的问题:
return await fetch(<URL>, { /* 配置不变 */ }) .then(res => res.text()) .then(text => { console.log('原始文本长度:', text.length); const resData = JSON.parse(text); console.log('解析后holdings长度:', resData.data.items[0].holdings.length); return resData.error ? null : resData; });
如果手动解析后长度正常,说明fetch的res.json()内部处理存在异常;如果同样异常,说明原始文本中存在隐性的JSON语法问题(如重复键、未转义字符),导致解析时丢失数据。
2. 检查后续函数对数据的篡改
在数据传递的关键节点打印日志,定位长度变化的环节:
.then((resData) => { if(!resData.error) { console.log('解析后初始长度:', resData.data.items[0].holdings.length); // 打印初始长度 const processedData = yourOtherFunction(resData); // 调用目标函数 console.log('函数处理后长度:', processedData.data.items[0].holdings.length); // 打印处理后长度 return resData; } });
重点检查目标函数中是否存在对holdings数组的截断操作(如slice(0,24)、filter条件过滤),或是响应式框架(如Vue/React)的响应式转换导致的数组长度显示异常。
3. 使用深拷贝隔离数据修改
如果后续函数存在隐性修改,可通过深拷贝生成独立副本传递,避免原数据被篡改:
.then((resData) => { if(!resData.error) { // 深拷贝生成独立副本 const clonedData = JSON.parse(JSON.stringify(resData)); console.log('深拷贝后长度:', clonedData.data.items[0].holdings.length); return clonedData; } });
如果深拷贝后长度正常且传递给函数后不再变化,说明原对象被其他代码引用并修改。
4. 检查JSON响应的合法性
将res.text()返回的原始文本复制到浏览器控制台的JSON.parse中,检查是否存在语法错误:
- 检查是否存在重复键:JSON规范中重复键会被最后一个值覆盖,可能导致数组项丢失
- 检查是否存在未转义的特殊字符(如换行符、引号)
- 检查数组是否存在非法尾逗号(部分解析器会忽略,但严格解析可能导致截断)
内容的提问来源于stack exchange,提问作者Josh Kroslowitz
相关产品推荐
相关产品推荐

