考虑以下代码:
fetch('https://www.reddit.com/r/javascript/json')
.then(res => res.text())
.then(() => {
console.log('SUCCESS');
})
.catch(err => {
console.log('FAIL');
})
它故意是错误的路线,并且它返回代码404的错误。但是,SUCCESS
情况正在触发。
但是,如果我将res => res.text()
替换为res => res.json()
,则会捕获FAIL
,因为它应该是。{/ p>
此外,即使使用FAIL
,放置绝对错误的网址(我的意思是不存在的服务器)也会导致正确的导线res.text()
。
我发现这种行为有点奇怪和棘手,并且会感激一些澄清。
P上。 S.我知道,这可能有助于这一预防措施:if (!res.ok) throw new Error();
,只是好奇为什么会这样做。
答案 0 :(得分:3)
它故意是错误的路线并且它返回代码404的错误。但是,SUCCESS案例正在触发。
这是设计的。 fetch
调用仅承诺发出请求并返回响应 - 任何响应。只有在出现网络问题时才会拒绝,例如更改域时不存在的服务器。
状态代码或正文内容在确定其是否有效的HTTP响应时无关紧要。要检查其状态是否成功,您必须按照您的说明测试res.ok
。
但是,如果我将
res => res.text()
替换为res => res.json()
,它会按照原样捕获失败。
是的,但那并不是因为请求失败了。它抛出是因为你的响应体不是有效的JSON - 它甚至可以与404一起使用。
答案 1 :(得分:2)
简短回答是您的承诺在res.json()
长答案(解释)
您的初始http调用成功,因此执行“成功”承诺
但是...... 即使你的电话实际上是成功的,当Promise中的任何地方抛出未处理的错误时,你总是会触发'失败'的承诺( catch ),这就是承诺的运作方式。
现在.... 基本上uri会返回html页面的文字表示,因此调用res.text()
成功,但是当您在'text'上调用res.json()
时数据它会抛出一个错误,因为响应不是json,并且该错误会冒泡并最终被承诺的捕获所捕获。如果你想要json,你必须首先知道你希望从你的响应中获得的数据类型,然后转换成你想要的。
课程这里知道您的返回类型,以便您了解期望和代码的内容,调用uri并且不知道它返回的数据类型是没有意义的。