Axios:基于 Promise 的 HTTP 客户端
历史简介:
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 受欢迎?
-
易用性:Axios 提供了一个简洁直观的 API,使发送 HTTP 请求变得非常简单。
-
基于 Promise:Axios 基于 Promise,这与现代 JavaScript 的异步处理方式一致。
-
功能强大:支持请求和响应拦截器、取消请求、自动转换 JSON 数据等功能。
-
跨环境:Axios 可以在浏览器和 Node.js 环境中使用,适应性强。
-
活跃的社区:有一个庞大而活跃的开发者社区,不断提供支持和改进。
总的来说,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 等),并具有许多有用的功能,例如:
-
请求和响应拦截器:可以在请求发送之前或响应接收之后进行一些处理。
-
自动转换 JSON 数据:Axios 会自动将 JSON 数据转换为 JavaScript 对象。
-
取消请求:可以在需要时取消正在进行的请求。
-
防止跨站请求伪造(CSRF) :通过自动包含 CSRF 令牌来帮助防止 CSRF 攻击。
-
处理超时:可以设置请求的超时时间。
-
上传和下载进度:可以监控文件上传和下载的进度。
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