likes
comments
collection
share

Axios:基于 Promise 的 HTTP 客户端

作者站长头像
站长
· 阅读数 16

历史简介:

Axios 是一个流行的 HTTP 客户端库,它的发展历史可以追溯到 2016 年。以下是关于 Axios 的一些关键发展和重要里程碑:

1. 创立和初期发展

  • 2016 年:Axios 由 Matt Zabriskie 创建和发布。它的设计灵感来源于 Angular 的 $http 服务,但其目标是提供一个独立于框架的 HTTP 客户端库。最初的版本很快受到了开发者社区的欢迎,因为它简洁易用,并且基于 Promise,适合现代 JavaScript 开发。

2. 社区和生态系统的增长

  • 2017-2018 年:随着越来越多的开发者采用 Axios,它的社区和生态系统迅速增长。许多开源项目和教程开始推荐 Axios 作为首选的 HTTP 客户端。GitHub 上的贡献者数量增加,库的功能也不断完善。

3. 版本更新和改进

  • 2019 年:Axios 发布了多个版本更新,进一步提高了稳定性和功能性。例如,增加了对拦截器、取消请求和更复杂的请求配置的支持。

  • 2020 年:Axios 的用户群体继续扩大,并且在 GitHub 上达到了超过 80,000 颗星。社区贡献者提交了许多改进,包括修复 bug 和优化性能。

4. 现代化和迁移

  • 2021 年:Axios 开始向更现代化的 JavaScript 规范过渡,增强对 TypeScript 的支持。这一举措吸引了更多的开发者,特别是那些使用 TypeScript 构建大型项目的团队。

  • 2022 年:Axios 的下载量继续增加,成为许多项目中的标准 HTTP 客户端选择。它的文档和社区支持也不断完善,使新用户更容易上手。

5. 未来发展

  • 2023 年及以后:Axios 仍然在积极开发中,目标是继续提高性能和扩展功能。社区贡献者和核心团队致力于保持 Axios 的现代化,并解决新出现的需求和挑战。

为什么 Axios 受欢迎?

  1. 易用性:Axios 提供了一个简洁直观的 API,使发送 HTTP 请求变得非常简单。

  2. 基于 Promise:Axios 基于 Promise,这与现代 JavaScript 的异步处理方式一致。

  3. 功能强大:支持请求和响应拦截器、取消请求、自动转换 JSON 数据等功能。

  4. 跨环境:Axios 可以在浏览器和 Node.js 环境中使用,适应性强。

  5. 活跃的社区:有一个庞大而活跃的开发者社区,不断提供支持和改进。

总的来说,Axios 通过不断的更新和改进,已经成为现代 Web 开发中不可或缺的工具之一。

请求接口的步骤

1. 配置请求

在发送请求之前,必须配置请求参数,例如 URL、请求方法(GET、POST 等)、请求头和请求体。

const config = {
  url: 'https://api.example.com/data',
  method: 'GET', // 请求方法
  headers: {
    'Content-Type': 'application/json', // 请求头
    'Authorization': 'Bearer YOUR_TOKEN' // 身份验证令牌(如果需要)
  },
  params: {
    key1: 'value1', // 查询参数
  },
  data: {
    key2: 'value2' // 请求体(POST、PUT 请求时)
  },
  timeout: 10000 // 超时时间
};

2. 发送请求

使用 Axios 等 HTTP 客户端库发送请求,并返回一个 Promise。此时请求会被发送到指定的服务器。

axios(config)
  .then(response => {
    // 处理响应
  })
  .catch(error => {
    // 处理错误
  });

3. 请求拦截器(可选)

在请求发送之前,可以使用请求拦截器对请求进行一些处理,例如添加身份验证令牌、修改请求配置等。

axios.interceptors.request.use(
  config => {
    const token = localStorage.getItem('authToken');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

4. 服务器处理请求

服务器接收到请求后,处理请求并返回响应。这个过程包括验证请求、查询数据库、执行业务逻辑等。

5. 接收响应

客户端接收到服务器的响应。响应包含状态码、响应头和响应数据。

axios(config)
  .then(response => {
    console.log('Response data:', response.data); // 响应数据
  })
  .catch(error => {
    console.error('Error:', error);
  });

6. 响应拦截器(可选)

在处理响应之前,可以使用响应拦截器对响应进行一些处理,例如统一错误处理、数据格式化等。

axios.interceptors.response.use(
  response => {
    return response;
  },
  error => {
    if (error.response) {
      // 服务器响应了一个状态码,不在2xx范围内
      console.error('Error response:', error.response.data);
    } else if (error.request) {
      // 请求已发送,但未收到响应
      console.error('Error request:', error.request);
    } else {
      // 发生了一些设置时的错误
      console.error('Error message:', error.message);
    }
    return Promise.reject(error);
  }
);

7. 处理响应数据

在接收到响应并通过(可选的)拦截器处理后,最终处理响应数据。这通常包括更新 UI、存储数据等。

axios(config)
  .then(response => {
    // 处理响应数据,例如更新状态或 UI
    updateUI(response.data);
  })
  .catch(error => {
    // 处理错误,例如显示错误消息
    showError(error);
  });

8. 错误处理

在请求过程中可能会发生各种错误,例如网络错误、服务器错误、请求超时等。需要处理这些错误,提供友好的用户提示或进行其他处理。

axios(config)
  .catch(error => {
    if (error.response) {
      // 服务器响应错误
      console.error('Server responded with status code:', error.response.status);
    } else if (error.request) {
      // 请求发送后未收到响应
      console.error('No response received:', error.request);
    } else {
      // 设置请求时发生错误
      console.error('Request setup error:', error.message);
    }
  });

从配置请求、发送请求到处理响应和错误,每个步骤都非常重要。通过封装这些步骤,可以使代码更简洁、更统一、更易于维护。使用 Axios 等工具库可以大大简化这些过程,使开发更加高效。

Axios是什么?

Axios 是一个基于 Promise 的 HTTP 客户端,主要用于浏览器和 Node.js 环境中。它提供了简洁的 API,用于发送 HTTP 请求,并处理响应。Axios 支持常见的 HTTP 方法(GET、POST、PUT、DELETE 等),并具有许多有用的功能,例如:

  1. 请求和响应拦截器:可以在请求发送之前或响应接收之后进行一些处理。

  2. 自动转换 JSON 数据:Axios 会自动将 JSON 数据转换为 JavaScript 对象。

  3. 取消请求:可以在需要时取消正在进行的请求。

  4. 防止跨站请求伪造(CSRF) :通过自动包含 CSRF 令牌来帮助防止 CSRF 攻击。

  5. 处理超时:可以设置请求的超时时间。

  6. 上传和下载进度:可以监控文件上传和下载的进度。

Axios怎么用?

1. 安装 Axios

首先,你需要在项目中安装 Axios。使用 npm 或 yarn 安装:

npm install axios
# 或者
yarn add axios

2. 基本使用

发送 GET 请求

这是最基本的用法,发送一个 GET 请求并处理响应:

import axios from 'axios';

axios.get('https://api.example.com/data')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error('Error fetching data:', error);
  });

发送 POST 请求

发送一个 POST 请求并附带数据:

import axios from 'axios';

const postData = {
  name: 'John Doe',
  email: 'john.doe@example.com'
};

axios.post('https://api.example.com/data', postData)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error('Error posting data:', error);
  });

3. 配置选项

使用配置对象

你可以通过配置对象来设置请求的各种选项:

import axios from 'axios';

const config = {
  method: 'get',
  url: 'https://api.example.com/data',
  headers: { 'X-Custom-Header': 'foobar' }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error('Error fetching data:', error);
  });

默认配置

你可以设置全局的默认配置,这样所有请求都会使用这些默认配置:

import axios from 'axios';

axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = 'Bearer YOUR_TOKEN';
axios.defaults.headers.post['Content-Type'] = 'application/json';

axios.get('/data')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error('Error fetching data:', error);
  });

4. 拦截器

请求拦截器

在请求发送前拦截并修改请求:

import axios from 'axios';

axios.interceptors.request.use(config => {
  config.headers.Authorization = `Bearer YOUR_TOKEN`;
  return config;
}, error => {
  return Promise.reject(error);
});

响应拦截器

在响应到达时拦截并处理响应:

import axios from 'axios';

axios.interceptors.response.use(response => {
  // 对响应数据做些什么
  return response;
}, error => {
  // 对响应错误做些什么
  return Promise.reject(error);
});

5. 错误处理

处理错误信息:

import axios from 'axios';

axios.get('https://api.example.com/data')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    if (error.response) {
      // 服务器响应了一个状态码,不在2xx范围内
      console.error('Error response:', error.response.data);
    } else if (error.request) {
      // 请求已发送,但未收到响应
      console.error('Error request:', error.request);
    } else {
      // 发生了一些设置时的错误
      console.error('Error message:', error.message);
    }
  });

6. 取消请求

如果你需要取消一个正在进行的请求,可以使用取消令牌:

import axios from 'axios';

const CancelToken = axios.CancelToken;
const source = CancelToken.source();

axios.get('https://api.example.com/data', {
  cancelToken: source.token
})
.then(response => {
  console.log(response.data);
})
.catch(error => {
  if (axios.isCancel(error)) {
    console.log('Request canceled', error.message);
  } else {
    console.error('Error fetching data:', error);
  }
});

// 取消请求
source.cancel('Operation canceled by the user.');

7. 上传和下载进度

监控上传和下载进度:

import axios from 'axios';

// 上传文件
const formData = new FormData();
formData.append('file', file);

axios.post('https://api.example.com/upload', formData, {
  onUploadProgress: progressEvent => {
    console.log('Upload Progress:', Math.round((progressEvent.loaded * 100) / progressEvent.total));
  }
})
.then(response => {
  console.log(response.data);
})
.catch(error => {
  console.error('Error uploading file:', error);
});

// 下载文件
axios.get('https://api.example.com/download', {
  onDownloadProgress: progressEvent => {
    console.log('Download Progress:', Math.round((progressEvent.loaded * 100) / progressEvent.total));
  }
})
.then(response => {
  console.log(response.data);
})
.catch(error => {
  console.error('Error downloading file:', error);
});

在实际开发中,我们不会直接拿官方的axios直接调用,而且选择自己封装一个axios

封装Axios的好处

1. 统一配置

通过封装,可以将所有请求的默认配置(如基础 URL、超时时间、请求头等)集中管理,避免在每个请求中重复配置。

const axiosInstance = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json',
  },
});

2. 统一错误处理

封装 Axios 后,可以在一个地方统一处理所有请求的错误。这样可以确保在出现错误时,能够以一致的方式处理和显示错误信息。

axiosInstance.interceptors.response.use(
  response => response,
  error => {
    if (error.response) {
      console.error('Error response:', error.response.data);
    } else if (error.request) {
      console.error('Error request:', error.request);
    } else {
      console.error('Error message:', error.message);
    }
    return Promise.reject(error);
  }
);

3. 统一拦截器

可以在封装中设置请求和响应的拦截器,比如在请求前自动添加认证令牌,或者在响应后统一处理特定的状态码(如 401 未授权)。

axiosInstance.interceptors.request.use(
  config => {
    const token = localStorage.getItem('authToken');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  error => Promise.reject(error)
);

4. 提高可维护性

将所有 HTTP 请求封装在一起,可以减少重复代码,使项目更易于维护。当 API 的 URL 或配置发生变化时,只需在封装的 Axios 实例中修改,而不需要修改所有请求的代码。

// 修改 baseURL 只需在 axiosInstance 中修改
const axiosInstance = axios.create({
  baseURL: 'https://newapi.example.com',
  timeout: 10000,
});

5. 简化使用

封装常用的请求方法后,使用时更加简洁,减少了代码冗余,提升了代码的可读性。

const api = {
  getData(endpoint, params) {
    return axiosInstance.get(endpoint, { params });
  },
  postData(endpoint, data) {
    return axiosInstance.post(endpoint, data);
  },
};

api.getData('/data', { param1: 'value1' })
  .then(response => console.log('Data fetched:', response.data))
  .catch(error => console.error('Error fetching data:', error));

6. 方便扩展

如果需要添加新的功能或处理逻辑,比如统一处理分页、缓存请求结果等,可以在封装中统一实现。

const api = {
  getPaginatedData(endpoint, page) {
    return axiosInstance.get(endpoint, { params: { page } });
  },
};

自己封装 Axios 能使代码更简洁、更统一、更易于维护,同时也为将来扩展和修改提供了便利。这对于大型项目尤其重要,可以帮助你在项目中更好地管理和处理 HTTP 请求。

封装Axios

1. 创建 Axios 实例

首先,创建一个 Axios 实例并配置一些默认选项。

import axios from 'axios';

// 创建 Axios 实例
const axiosInstance = axios.create({
  baseURL: 'https://api.example.com', // 设置基础 URL
  timeout: 10000, // 设置请求超时时间
  headers: {
    'Content-Type': 'application/json',
  },
});

export default axiosInstance;

2. 配置拦截器

配置请求和响应拦截器,在发送请求和接收响应之前进行一些处理。

import axiosInstance from './axiosInstance';

// 请求拦截器
axiosInstance.interceptors.request.use(
  config => {
    // 在发送请求之前做些什么
    const token = localStorage.getItem('authToken');
    if (token) {
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  error => {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

// 响应拦截器
axiosInstance.interceptors.response.use(
  response => {
    // 对响应数据做些什么
    return response;
  },
  error => {
    // 对响应错误做些什么
    if (error.response) {
      console.error('Error response:', error.response.data);
    } else if (error.request) {
      console.error('Error request:', error.request);
    } else {
      console.error('Error message:', error.message);
    }
    return Promise.reject(error);
  }
);

export default axiosInstance;

3. 封装常用请求方法

封装一些常用的请求方法,使其在项目中更容易使用。

import axiosInstance from './axiosInstance';

const api = {
  // GET 请求
  get(endpoint, params) {
    return axiosInstance.get(endpoint, { params });
  },
  
  // POST 请求
  post(endpoint, data) {
    return axiosInstance.post(endpoint, data);
  },
  
  // PUT 请求
  put(endpoint, data) {
    return axiosInstance.put(endpoint, data);
  },
  
  // DELETE 请求
  delete(endpoint) {
    return axiosInstance.delete(endpoint);
  },
  
  // 文件上传
  upload(endpoint, file) {
    const formData = new FormData();
    formData.append('file', file);
    return axiosInstance.post(endpoint, formData, {
      headers: {
        'Content-Type': 'multipart/form-data',
      },
      onUploadProgress: progressEvent => {
        console.log('Upload Progress:', Math.round((progressEvent.loaded * 100) / progressEvent.total));
      }
    });
  }
};

export default api;

4. 在项目中使用封装好的 API

现在你可以在项目中使用封装好的 API,使代码更简洁和易维护。

import api from './api';

// 获取数据
api.get('/data', { param1: 'value1' })
  .then(response => {
    console.log('Data fetched:', response.data);
  })
  .catch(error => {
    console.error('Error fetching data:', error);
  });

// 提交数据
const postData = { name: 'John Doe', email: 'john.doe@example.com' };
api.post('/data', postData)
  .then(response => {
    console.log('Data posted:', response.data);
  })
  .catch(error => {
    console.error('Error posting data:', error);
  });

// 上传文件
const file = document.querySelector('#fileInput').files[0];
api.upload('/upload', file)
  .then(response => {
    console.log('File uploaded:', response.data);
  })
  .catch(error => {
    console.error('Error uploading file:', error);
  });

总结

Axios 是一个功能强大且灵活的 HTTP 客户端,可以通过封装来简化和统一 HTTP 请求处理。在封装过程中,可以设置默认配置、添加拦截器、统一错误处理等,从而提高代码的可维护性和可读性。

转载自:https://juejin.cn/post/7397285315809607706
评论
请登录