排查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;
    }
  }
}
posted @ 2022-07-21 18:18  韭菜茄子  阅读(8597)  评论(0编辑  收藏  举报