排查JSON解析报错Uncaught SyntaxError: Unexpected token < in JSON at position 0
首先在埋点系统无法通过souremap看到错误信息,只能根据页面进行综合判断,发现页面代码也没有JSON.parse的使用,只有接口返回会用到。
JSON 值可以是:
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true 或 false)
数组(在中括号中)
对象(在大括号中)
null
以<开始的返回值会有Unexpected token <这样的提示。
<这个符号意味着返回值是HTML而不是JSON。
其他解析错误类型如下:
JSON.parse(''); // SyntaxError,待解析的字符串不能为空
JSON.parse('{"x": 1}'); // {x: 1}, 属性必须用双引号括起来
JSON.parse('{"x": 1,}'); // SyntaxError,最后一个属性不能有逗号
JSON.parse('[1,2,]'); // SyntaxError,最后一个属性不能有逗号
JSON.parse('001'); // SyntaxError, 数字禁止有前导0
JSON.parse('11a'); // SyntaxError,不符合数值格式
JSON.parse('1.'); // SyntaxError,如果有小数点,则小数点后至少有一位数字
JSON.parse('"\n"'); // SyntaxError,控制字符不能被解析
JSON.parse(undefined); // SyntaxError
JSON.parse(NaN); // SyntaxError
JSON.parse(Infinity); // SyntaxError
控制台进行操作演示常见的JSON解析错误:
模拟两种接口返回解析报错:
1、模拟服务器5xx报错,然后客户端请求后进行res.json会报json解析错误(其实就是解析了JSON.parse(undefined));
2、服务器返回html或者其他无法解析的json类型,也会出现解析错误,另外:res.ok为true即(response status 200-299)跟返回结果是否可以解析为json没有关系
// 处理方法, 先判断返回的数据是否可以被解析为json, 可以的话才调用.json() 方法
fetch('http://localhost:9000/yyy', { method: 'POST', }) .then(async (response) => { // 克隆一份返回数据流 因为只能被解析一次 判断返回结果是否可以被JSON.parse const rpsStr = await response.clone().text(); try { JSON.parse(rpsStr); return response.json(); } catch (e) { return response.text(); } }) .then((result) => { console.log('Success:', result); }) .catch((error) => { console.error('Error:', error); })
// 公共方法
/** * 判断字符串是否可以被JSON.parse 避免解析错误 * @param str * @returns {boolean} */ export function isJSON(str) { if (typeof str === 'string') { try { JSON.parse(str); return true; } catch (e) { return false; } } }