Fetch Request--强大的原生JavaScript API

异步(基于 Promise)与 XMLHttpRequest 类似

全局的 fetch() 方法用于发起获取资源的请求。它返回一个 promise,这个 promise 会在请求响应后被 resolve,并传回 Response 对象。

语法:Promise<Response> fetch(input[, init]);

介绍详见mdn

1.fetch 是一个用于发起 HTTP 请求的原生 JavaScript 函数。与 axios 类似,我们也可以对 fetch 进行封装,使得在项目中使用起来更加方便。

以下是一个简单的 fetch 封装示例:

const fetch = (url, options) => {
  // 对 options 参数进行处理
  options = Object.assign(
    {
      credentials: 'same-origin'
    },
    options
  );
  // 发起请求
  return window.fetch(url, options).then(response => {
    // 对响应数据进行处理
    if (response.status >= 200 && response.status < 300) {
      return response.json();
    } else {
      return Promise.reject(new Error(response.statusText));
    }
  });
};

export default fetch;

2.fetch 缺点

fetch 本身是一个很好的发起 HTTP 请求的工具,但是它有一些缺点:

  • 不支持超时处理。如果请求超时,fetch 不会自动中断请求,而是会一直等待服务器响应。
  • 不支持自动重试。如果请求失败,fetch 不会自动重新发起请求。
  • 不支持拦截器。在发起请求和接收响应时,无法通过拦截器对请求和响应进行处理。

因此,在实际项目中,我们通常会选择使用 axios 或者其他类似的库来发起 HTTP 请求。

3.改进

  • 使用超时库。例如,你可以使用 "fetch-timeout" 库来为 fetch 添加超时处理。
import fetchTimeout from 'fetch-timeout';

const fetch = (url, options, timeout = 5000) => {
  return fetchTimeout(url, options, timeout).catch(error => {
    if (error.name === 'FetchTimeoutError') {
      // 处理超时错误
    } else {
      // 处理其他错误
    }
  });
};
  • 使用重试库。例如,你可以使用 "fetch-retry" 库来为 fetch 添加重试功能。
import fetchRetry from 'fetch-retry';

const fetch = (url, options, retries = 3, retryDelay = 1000) => {
  return fetchRetry(url, options, retries, retryDelay).catch(error => {
    // 处理错误
  });
};
  • 使用拦截器库。例如,你可以使用 "fetch-intercept" 库来为 fetch 添加拦截器功能。

     

import fetchIntercept from 'fetch-intercept';

fetchIntercept.register({
  request: function(url, config) {
    // 在发起请求之前做一些处理
    return [url, config];
  },

  requestError: function(error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  },

  response: function(response) {
    // 对响应数据做一些处理
    return response;
  },

  responseError: function(error) {
    // 对响应错误做些什么
    return Promise.reject(error);
  }
});

// 使用 fetch 函数发起请求
fetch('/users')
  .then(res => {
    console.log(res);
  })
  .catch(error => {
    console.log(error);
  });
4.将超时、重试、拦截器等功能组合在一起使用
import fetchTimeout from 'fetch-timeout';
import fetchRetry from 'fetch-retry';
import fetchIntercept from 'fetch-intercept';

const fetch = (url, options, timeout = 5000, retries = 3, retryDelay = 1000) => {
  return fetchTimeout(url, options, timeout)
    .then(response => {
      if (response.status >= 200 && response.status < 300) {
        return response.json();
      } else {
        return Promise.reject(new Error(response.statusText));
      }
    })
    .catch(error => {
      if (error.name === 'FetchTimeoutError') {
        // 处理超时错误
      } else {
        return fetchRetry(url, options, retries, retryDelay).catch(error => {
          // 处理其他错误
        });
      }
    });
};

fetchIntercept.register({
  request: function(url, config) {
    // 在发起请求之前做一些处理
    return [url, config];
  },

  requestError: function(error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  },

  response: function(response) {
    // 对响应数据做一些处理
    return response;
  },

  responseError: function(error) {
    // 对响应错误做些什么
    return Promise.reject(error);
  }
});

// 使用 fetch 函数发起请求
fetch('/users')
  .then(res => {
    console.log(res);
  })
  .catch(error => {
    console.log(error);
  });

5.使用示例

  • 使用 fetch.get 发起 GET 请求:
fetch.get('/users').then(res => {
  console.log(res);
});
  • 使用 fetch.post 发起 POST 请求:
fetch.post('/users', {
  body: JSON.stringify({
    name: 'John',
    age: 30
  }),
  headers: {
    'Content-Type': 'application/json'
  }
}).then(res => {
  console.log(res);
});
  • 使用 fetch.put 发起 PUT 请求:
fetch.put('/users/1', {
  body: JSON.stringify({
    name: 'John',
    age: 30
  }),
  headers: {
    'Content-Type': 'application/json'
  }
}).then(res => {
  console.log(res);
});
  • 使用 fetch.delete 发起 DELETE 请求:
fetch.delete('/users/1').then(res => {
  console.log(res);
});

6.总结

不管使用哪种库来发起 HTTP 请求,都要注意确保代码的可读性和可维护性。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值