使用 fetch() 处理失败的 HTTP 响应

﹏ヽ暗。殇╰゛Y 2023-10-01 18:59 60阅读 0赞

测验:对网络新fetch()API的调用有什么作用?

  1. fetch("http://httpstat.us/500")
  2. .then(function() {
  3. console.log("ok");
  4. }).catch(function() {
  5. console.log("error");
  6. });

如果你像我一样,你可能会认为这段代码在运行时会记录“错误”——但实际上它会记录“ok”。

这种期望可能来自多年的 jQuery 开发,因为jQuery 的ajax()方法fail在响应包含失败的 HTTP 状态代码时调用其处理程序。例如,下面的代码在运行时会记录“错误”:

  1. $.ajax("http://httpstat.us/500")
  2. .done(function() {
  3. console.log("ok");
  4. }).fail(function() {
  5. console.log("error");
  6. });

为什么会这样fetch()工作?

根据 MDN,fetch()API 仅在遇到“网络错误”时才会拒绝承诺,尽管这通常意味着权限问题或类似问题。” 基本上fetch()只会在用户离线,或者发生一些不太可能的网络错误,例如 DNS 查找失败时才会拒绝一个 promise。

好消息是fetch提供了一个简单的ok标志来指示 HTTP 响应的状态代码是否在成功范围内。例如以下代码记录“错误:内部服务器错误(…)”:

  1. fetch("http://httpstat.us/500")
  2. .then(function(response) {
  3. if (!response.ok) {
  4. throw Error(response.statusText);
  5. }
  6. return response;
  7. }).then(function(response) {
  8. console.log("ok");
  9. }).catch(function(error) {
  10. console.log(error);
  11. });

为了保持此代码干燥和可重用,您可能想要创建一个通用错误处理函数,您可以将其用于所有fetch()调用。以下代码将错误处理重构为一个handleErrors()函数:

  1. function handleErrors(response) {
  2. if (!response.ok) {
  3. throw Error(response.statusText);
  4. }
  5. return response;
  6. }
  7. fetch("http://httpstat.us/500")
  8. .then(handleErrors)
  9. .then(function(response) {
  10. console.log("ok");
  11. }).catch(function(error) {
  12. console.log(error);
  13. });

为了增加乐趣,您可以使用ES6 箭头函数来使回调格式不那么冗长:

  1. function handleErrors(response) {
  2. if (!response.ok) {
  3. throw Error(response.statusText);
  4. }
  5. return response;
  6. }
  7. fetch("http://httpstat.us/500")
  8. .then(handleErrors)
  9. .then(response => console.log("ok") )
  10. .catch(error => console.log(error) );

离别的思念

尽管我仍然不喜欢fetch()‘ 拒绝失败的 HTTP 状态代码的缺乏,但随着时间fetch()的推移,我的行为越来越多——主要是因为它让我可以更好地控制我如何处理个别问题。另外,它的可组合性fetch()使得手动处理错误而不添加一堆冗长的代码变得相当简单。

总的来说,我认为值得花几分钟来玩fetch(),即使只是看看你的想法。它肯定是比 XMLHttpRequest 更具可读性的替代方案。如果您碰巧正在构建NativeScript应用程序,您可能不知道您现在可以使用而不fetch()需要任何 polyfill 或后备。还有一些关于fetch()在原生 Android 和 iOS 应用程序中执行 HTTP 请求的东西简直太酷了 :)

发表评论

表情:
评论列表 (有 0 条评论,60人围观)

还没有评论,来说两句吧...

相关阅读