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
的错误处理机制,就需要了解 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))
虽然浏览器报错了 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
返回的 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 一一配对。
"一个 promise 成功后可以触发后面的多个 then,以前我以为必须每一个 then 里再返回一个 promise 对象才能继续执行下一个 then。结果发现不用。"
返回的值相当于Promise.resolve(returnValue)了