Request网络请求如何封装

发布时间:2022-10-17 13:59:17 作者:iii
来源:亿速云 阅读:213

Request网络请求如何封装

在现代Web开发中,网络请求是不可或缺的一部分。无论是前端还是后端,我们都需要与服务器进行数据交互。为了提高代码的可维护性和复用性,封装网络请求是一个常见的做法。本文将详细介绍如何封装网络请求,涵盖从基础封装到高级功能的实现。

1. 为什么需要封装网络请求

在开发过程中,我们可能会遇到以下问题:

通过封装网络请求,我们可以解决上述问题,提高代码的可读性、可维护性和复用性。

2. 基础封装

2.1 使用Fetch API

Fetch API是现代浏览器提供的一个用于发起网络请求的接口。我们可以基于Fetch API进行封装。

class HttpClient {
  constructor(baseURL) {
    this.baseURL = baseURL;
  }

  async request(endpoint, options = {}) {
    const url = `${this.baseURL}${endpoint}`;
    const response = await fetch(url, {
      ...options,
      headers: {
        'Content-Type': 'application/json',
        ...options.headers,
      },
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    return response.json();
  }

  get(endpoint, options = {}) {
    return this.request(endpoint, {
      ...options,
      method: 'GET',
    });
  }

  post(endpoint, body, options = {}) {
    return this.request(endpoint, {
      ...options,
      method: 'POST',
      body: JSON.stringify(body),
    });
  }

  put(endpoint, body, options = {}) {
    return this.request(endpoint, {
      ...options,
      method: 'PUT',
      body: JSON.stringify(body),
    });
  }

  delete(endpoint, options = {}) {
    return this.request(endpoint, {
      ...options,
      method: 'DELETE',
    });
  }
}

// 使用示例
const api = new HttpClient('https://api.example.com');
api.get('/users')
  .then(data => console.log(data))
  .catch(error => console.error(error));

2.2 使用Axios

Axios是一个基于Promise的HTTP客户端,适用于浏览器和Node.js。它提供了更丰富的功能和更好的错误处理机制。

import axios from 'axios';

class HttpClient {
  constructor(baseURL) {
    this.client = axios.create({
      baseURL,
      headers: {
        'Content-Type': 'application/json',
      },
    });
  }

  async request(config) {
    try {
      const response = await this.client.request(config);
      return response.data;
    } catch (error) {
      throw new Error(`HTTP error! status: ${error.response?.status}`);
    }
  }

  get(endpoint, config = {}) {
    return this.request({
      ...config,
      method: 'GET',
      url: endpoint,
    });
  }

  post(endpoint, data, config = {}) {
    return this.request({
      ...config,
      method: 'POST',
      url: endpoint,
      data,
    });
  }

  put(endpoint, data, config = {}) {
    return this.request({
      ...config,
      method: 'PUT',
      url: endpoint,
      data,
    });
  }

  delete(endpoint, config = {}) {
    return this.request({
      ...config,
      method: 'DELETE',
      url: endpoint,
    });
  }
}

// 使用示例
const api = new HttpClient('https://api.example.com');
api.get('/users')
  .then(data => console.log(data))
  .catch(error => console.error(error));

3. 高级封装

3.1 请求拦截器

请求拦截器可以在请求发送之前或响应到达之后对其进行处理。例如,我们可以在请求发送之前添加认证信息,或在响应到达之后统一处理错误。

class HttpClient {
  constructor(baseURL) {
    this.client = axios.create({
      baseURL,
      headers: {
        'Content-Type': 'application/json',
      },
    });

    // 请求拦截器
    this.client.interceptors.request.use(
      config => {
        const token = localStorage.getItem('token');
        if (token) {
          config.headers.Authorization = `Bearer ${token}`;
        }
        return config;
      },
      error => {
        return Promise.reject(error);
      }
    );

    // 响应拦截器
    this.client.interceptors.response.use(
      response => {
        return response.data;
      },
      error => {
        if (error.response?.status === 401) {
          // 处理未授权错误
          console.error('Unauthorized');
        }
        return Promise.reject(error);
      }
    );
  }

  // 其他方法...
}

3.2 请求取消

在某些情况下,我们可能需要取消正在进行的请求。例如,当用户快速切换页面时,取消之前的请求可以避免不必要的网络流量和潜在的竞态条件。

class HttpClient {
  constructor(baseURL) {
    this.client = axios.create({
      baseURL,
      headers: {
        'Content-Type': 'application/json',
      },
    });

    this.cancelTokenSource = axios.CancelToken.source();
  }

  async request(config) {
    try {
      const response = await this.client.request({
        ...config,
        cancelToken: this.cancelTokenSource.token,
      });
      return response.data;
    } catch (error) {
      if (axios.isCancel(error)) {
        console.log('Request canceled', error.message);
      } else {
        throw new Error(`HTTP error! status: ${error.response?.status}`);
      }
    }
  }

  cancelRequest() {
    this.cancelTokenSource.cancel('Operation canceled by the user.');
    this.cancelTokenSource = axios.CancelToken.source(); // 重新创建取消令牌
  }

  // 其他方法...
}

// 使用示例
const api = new HttpClient('https://api.example.com');
api.get('/users')
  .then(data => console.log(data))
  .catch(error => console.error(error));

// 取消请求
api.cancelRequest();

3.3 请求重试

在网络不稳定的情况下,请求可能会失败。我们可以实现请求重试机制,以提高请求的成功率。

class HttpClient {
  constructor(baseURL, maxRetries = 3) {
    this.client = axios.create({
      baseURL,
      headers: {
        'Content-Type': 'application/json',
      },
    });
    this.maxRetries = maxRetries;
  }

  async request(config, retries = 0) {
    try {
      const response = await this.client.request(config);
      return response.data;
    } catch (error) {
      if (retries < this.maxRetries) {
        return this.request(config, retries + 1);
      }
      throw new Error(`HTTP error! status: ${error.response?.status}`);
    }
  }

  // 其他方法...
}

3.4 请求缓存

在某些场景下,我们可能希望缓存请求结果,以减少重复请求的网络开销。

class HttpClient {
  constructor(baseURL) {
    this.client = axios.create({
      baseURL,
      headers: {
        'Content-Type': 'application/json',
      },
    });
    this.cache = new Map();
  }

  async request(config) {
    const cacheKey = JSON.stringify(config);
    if (this.cache.has(cacheKey)) {
      return this.cache.get(cacheKey);
    }

    try {
      const response = await this.client.request(config);
      this.cache.set(cacheKey, response.data);
      return response.data;
    } catch (error) {
      throw new Error(`HTTP error! status: ${error.response?.status}`);
    }
  }

  // 其他方法...
}

4. 总结

通过封装网络请求,我们可以显著提高代码的可维护性和复用性。本文介绍了如何使用Fetch API和Axios进行基础封装,并探讨了请求拦截器、请求取消、请求重试和请求缓存等高级功能。希望这些内容能帮助你在实际项目中更好地管理和优化网络请求。

推荐阅读:
  1. 小程序-网络请求封装
  2. java webserver-封装request请求协议

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

request

上一篇:vmware上ubuntu怎么连接外网

下一篇:怎么用C语言解决回文日期问题

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》