JSON.parse()与.json()方法有何区别?为何fetch代码中前者失效?
JSON.parse() 与 Response.json() 的核心区别
很多人会误以为这两个方法可以互相替代,但它们的设计目的、处理对象和执行逻辑完全不同,下面逐一拆解:
1. 处理的对象根本不一样
JSON.parse()只认JSON格式的字符串,比如你得传'{"key":"value"}'这种符合JSON语法的字符串给它,它才能解析成JavaScript对象。如果传的是其他类型(比如你的代码里的Response对象),直接就会报错。Response.json()是fetch返回的Response对象专属方法,它的工作流程是:先读取Response的响应体数据流,把流转换成JSON格式的字符串,最后再调用类似JSON.parse()的逻辑把字符串转成JS对象。它的输入是Response对象,输出是解析后的JS对象(通过Promise异步返回)。
2. 同步/异步属性不同
JSON.parse()是同步方法,调用后立即执行解析,要是解析的字符串特别大,会阻塞后续代码执行。Response.json()是异步方法,返回一个Promise,必须用await或者.then()才能拿到结果——因为它要读取网络响应的数据流,这个过程是异步的,不能同步完成。
3. Response的响应体只能被读取一次
fetch返回的Response对象的响应体是一个「可读流」,一旦你调用了res.json()(或者res.text()、res.blob()这类读取流的方法),这个流就会被彻底消耗掉,没法再读取第二次。
结合你的代码解释错误原因
你代码里的res.json()能正常工作,是因为它正确处理了Response的响应体流,异步完成了解析。而JSON.parse(res)直接把Response对象传给了只接受字符串的JSON.parse(),这相当于给它塞了一个复杂对象,自然会抛出语法错误。
就算你想先用字符串再解析,也得注意不能和res.json()同时用,因为流已经被消耗了,正确的写法只能二选一:
const URL = "...some url..."; const getResponse = async () => { const res = await fetch(URL); // 方案1:直接用res.json() const data = await res.json(); console.log(data); // 方案2:先转字符串再解析(不能和方案1同时执行) // const resText = await res.text(); // const data1 = JSON.parse(resText); // console.log(data1); }
内容的提问来源于stack exchange,提问作者SDS
相关产品推荐
相关产品推荐

