Saber 酱的抱枕

Fly me to the moon

01/18
2019
学习

Fetch 的错误处理

JavaScript 的 Fetch 方法可以在大部分场景取代传统的 XMLHttpRequest 请求,或者 jQuery 的 $.ajax 方法。但是 Fetch 如何进行错误处理呢?

对于严重的错误,Fetch 会报错,因为这次请求是失败的,比如请求不存在的网址,或者因为跨域被禁止的网址,或者网络超时,这时候根本无法和服务器建立连接。这时 catch 会捕捉到错误信息:

fetch('https://ssss/')
.then(res=>res.text())
.then(data=>console.log(data))
.catch(err=>console.log(err))

Fetch 的错误处理

要理解上面代码的执行以及 Fetch 的错误处理机制,就需要了解 Promise 对象。Fetch 运行时会建立一个 Promise 对象,根据运行结果,这个对象可能进入成功状态(resolved),继续执行第二行的代码;也可能进入失败状态(reject),则执行 catch

但遇到 403、404、500 之类异常状态码,catch 却没有捕捉到错误。如下:

fetch('https://saber.love/f/')
.then(res=>res.text())
.then(data=>console.log(data))
.catch(err=>console.log(err))

Fetch 的错误处理

虽然浏览器报错了 403,但是代码依旧输出了返回的结果,没有触发 catch 里的错误。这是因为这次请求成功和服务器建立了连接Fetch 的结果是成功的(resolved),所以就照常进入了第二行代码(then)。我们可以在这里面手动分析一下错误,然后手动返回一个失败(reject)状态的 Promise 对象,使代码接下来进入 catch 执行。

fetch('https://saber.love/f/')
.then(res=>{
	console.log(res);
	if (res.ok) {
		return res.text();
	}else{
		return Promise.reject(res.status);
	}
})
.then(data=>console.log(data))
.catch(err=>console.log('状态码:'+err))

Fetch 的错误处理

第二步我打印了 Fetch 返回的 Response 对象,可以用里面的 ok 属性来判断请求是否出现了问题,或者自己根据状态码判断。如果出现了问题,手动创建一个失败的 Promise 对象,进入 catch 处理错误。


补充知识:

fetch('https://cdn.jsdelivr.net/npm/@trigrou/[email protected]/WebContent/zip.js')
.then(console.log(11))
.then(console.log(22))
.then(console.log(33))

一个 promise 成功后可以触发后面的多个 then,以前我以为必须每一个 then 里再返回一个 promise 对象才能继续执行下一个 then。结果发现不用。

catch 前面有多个 then 的话,可以捕获所有的 then 的异常处理,不需要和 then 一一配对。

Fetch 的错误处理

  1. 雪莲果
    Google Chrome 67Google Chrome 67WindowsWindows

    Fetch几个问题:旧的浏览器不支持Promise更不支持Fetch;只有网络错误会reject,遇到4xx、5xx的错误状态码还要自己用判断;必须用Promise异步来做;没有取消请求、没有查看完成进度(例如上传大文件的时候要看进度)的回调;返回的Response对象是只能读取一次的,除非事先用clone( )克隆一份……

    回复