1. Axios 概述
Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js。它具有以下特点:
- 支持浏览器和 Node.js 环境
- 支持 Promise API
- 可以拦截请求和响应
- 转换请求和响应数据
- 取消请求
- 自动转换 JSON 数据
2. Axios 的基本使用
发送 GET 请求
axios.get('https://api.example.com/data')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
发送 POST 请求
axios.post('https://api.example.com/submit', {
key: 'value'
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
3. Axios 配置选项
你可以通过配置对象来调整请求的行为:
axios({
method: 'post',
url: 'https://api.example.com/submit',
data: {
key: 'value'
},
headers: {
'Content-Type': 'application/json'
}
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
4. 创建 Axios 实例
可以创建预配置的 Axios 实例:
const instance = axios.create({
baseURL: 'https://api.example.com',
timeout: 1000,
headers: {'X-Custom-Header': 'foobar'}
});
5. 请求和响应拦截器
请求拦截器
axios.interceptors.request.use(
function(config) {
// 在发送请求之前做一些事情
return config;
},
function(error) {
// 处理请求错误
return Promise.reject(error);
}
);
响应拦截器
axios.interceptors.response.use(
function(response) {
// 对响应数据做点什么
return response;
},
function(error) {
// 对响应错误做点什么
return Promise.reject(error);
}
);
6. 错误处理
当使用 Axios 发送请求时,如果请求失败,Promise 将会被 reject,并且可以在 .catch()
块中捕获这个错误。下面是一个具体的示例:
axios.get('https://api.example.com/data')
.then(response => {
console.log('Data received:', response.data);
})
.catch(error => {
console.error('An error occurred:', error);
// 你可以检查错误的不同属性来确定错误的类型
if (error.response) {
// 请求已发出,服务器也响应了状态码,但状态码不在 2xx 范围内
console.log('Server responded with a status of:', error.response.status);
console.log('Response data:', error.response.data);
} else if (error.request) {
// 请求已发出,但没有收到响应
console.log('No response received:', error.request);
} else {
// 设置请求时发生了错误
console.log('Error setting up the request:', error.message);
}
console.log('Error config:', error.config);
});
在这个示例中,我们向 'https://api.example.com/data'
发送了一个 GET 请求。如果请求成功,我们将接收到服务器返回的数据;但如果请求失败,.catch()
块将被触发,你可以在其中处理错误。
错误对象 error
包含了许多有用的信息,比如:
error.response
:包含服务器的响应,如果有的话。它是一个包含data
、status
和headers
属性的对象。error.request
:包含创建的 XMLHttpRequest 对象,如果请求已经发出并且没有收到响应的话。error.message
:描述错误的字符串。error.config
:包含发送请求时的配置信息。
通过检查这些属性,可以更准确地定位错误原因,并采取相应的措施。例如,如果服务器返回了一个 404 错误,可能需要检查请求的 URL 是否正确;如果是 500 内部服务器错误,可能需要联系服务器管理员或开发者查看服务器日志。
7. 取消请求
可以创建一个 CancelToken 并在需要时取消请求:
const source = axios.CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(thrown => {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.message);
} else {
// handle error
}
});
// 取消请求
source.cancel('Operation canceled by the user.');
8. 封装 Axios
封装 Axios 可以让代码更整洁,更容易管理。可以在一个模块中封装所有的请求方法:
import axios from 'axios';
const apiClient = axios.create({
baseURL: 'https://api.example.com',
timeout: 1000,
});
// 封装 GET 请求
const get = (url, params) => apiClient.get(url, { params }).then(res => res.data);
// 封装 POST 请求
const post = (url, data) => apiClient.post(url, data).then(res => res.data);
// 封装 PUT 请求
const put = (url, data) => apiClient.put(url, data).then(res => res.data);
// 封装 DELETE 请求
const del = url => apiClient.delete(url).then(res => res.data);
// 封装 PATCH 请求
const patch = (url, data) => apiClient.patch(url, data).then(res => res.data);
// 导出这些方法
export { get, post, put, del, patch };
9. 高级用法
高级请求通常涉及更复杂的场景,例如处理大量并发请求、错误重试、请求取消、请求和响应的转换、自定义请求和响应拦截器等。下面我将通过一些具体的例子来展示这些高级用法。
1. 并发请求
当需要同时发送多个请求并等待所有请求完成时,可以使用 Promise.all
或者 axios.all
方法:
axios.all([
axios.get('https://api.example.com/users'),
axios.get('https://api.example.com/posts')
])
.then(axios.spread((usersResponse, postsResponse) => {
console.log(usersResponse.data);
console.log(postsResponse.data);
}))
.catch(errors => {
console.error(errors);
});
2. 错误重试
在某些情况下,可能需要在请求失败后自动重试。这可以通过使用中间件或自定义拦截器来实现:
const retryInterceptor = axios.interceptors.response.use(
response => response,
async error => {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true;
try {
const response = await axios.post('/auth/token');
const token = response.data.token;
originalRequest.headers['Authorization'] = `Bearer ${token}`;
return axios(originalRequest);
} catch (_error) {
return Promise.reject(_error);
}
}
return Promise.reject(error);
}
);
3. 请求取消
在某些情况下,可能需要在请求发送后取消它。这可以通过 CancelToken
来实现:
const source = axios.CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
})
.then(response => {
console.log(response.data);
})
.catch(throwError => {
if (axios.isCancel(throwError)) {
console.log('Request canceled', throwError.message);
} else {
console.error('A request failed:', throwError);
}
});
// 后面的某个时刻,取消请求
source.cancel('Operation canceled by the user.');
4. 请求和响应转换
可能需要在发送请求或接收到响应之前转换数据,例如序列化或反序列化数据:
axios({
url: '/foo',
method: 'post',
data: { bar: 'baz' },
transformRequest: [function(data) {
// 将请求数据转换成字符串
return JSON.stringify({ ...data });
}],
transformResponse: [function(data) {
// 将响应数据转换成 JSON 对象
return JSON.parse(data);
}]
})
.then(response => {
console.log(response.data);
});
5. 自定义请求和响应拦截器
拦截器允许在请求被发送或响应被处理之前修改它们:
axios.interceptors.request.use(request => {
// 在请求发送之前做一些事情
console.log('Sending request:', request);
return request;
}, error => {
// 处理请求错误
return Promise.reject(error);
});
axios.interceptors.response.use(response => {
// 在响应被传递给 then 前做一些事情
console.log('Received response:', response);
return response;
}, error => {
// 处理响应错误
return Promise.reject(error);
});
通过这些高级功能,可以根据不同的需求定制 Axios 的行为,以满足复杂的应用场景。在实际开发中,结合业务需求选择合适的策略是非常重要的。
10. 性能优化
使用缓存、优化请求头和压缩技术是提高网络请求效率和性能的重要手段。下面将针对这三点给出具体的示例。
1. 使用缓存机制
示例: 使用 axios-cache-adapter
库来缓存响应,减少不必要的网络请求。
首先,需要安装 axios-cache-adapter
:
npm install axios-cache-adapter
然后,在代码中使用它:
import axios from 'axios';
import CacheAdapter from 'axios-cache-adapter';
const cache = new CacheAdapter({
maxAge: 60 * 1000, // 缓存有效期为1分钟
});
const cachedAxios = axios.create({
adapter: cache.adapter,
});
// 发送请求,如果缓存中有数据则不会再次请求
cachedAxios.get('https://api.example.com/data')
.then(response => {
console.log('Data received:', response.data);
})
.catch(error => {
console.error('An error occurred:', error);
});
2. 优化请求头
示例: 仅在需要时发送特定的请求头,例如 If-None-Match
或 If-Modified-Since
,以利用 HTTP 的条件请求。
import axios from 'axios';
let lastModified;
axios.get('https://api.example.com/data', {
headers: {
'If-Modified-Since': lastModified,
},
})
.then(response => {
console.log('Data received:', response.data);
lastModified = response.headers['last-modified'];
})
.catch(error => {
if (error.response && error.response.status === 304) {
console.log('Data has not been modified since the last request');
} else {
console.error('An error occurred:', error);
}
});
在这个例子中,如果服务器的数据没有改变,它会返回一个 304 Not Modified 的状态码,客户端就可以使用缓存中的数据,而无需下载新的数据。
3. 使用压缩技术
示例: 通过设置 Accept-Encoding
请求头来请求压缩的数据。
import axios from 'axios';
axios.get('https://api.example.com/data', {
headers: {
'Accept-Encoding': 'gzip, deflate, br', // 支持 gzip, deflate 和 Brotli 压缩
},
})
.then(response => {
console.log('Data received:', response.data);
})
.catch(error => {
console.error('An error occurred:', error);
});
服务器如果支持压缩,会根据请求头中的 Accept-Encoding
字段来选择合适的压缩算法对响应体进行压缩,从而减少传输数据的大小,加快响应速度。
通过实施这些策略,可以显著提升应用的性能,减少用户的等待时间,同时降低服务器的带宽消耗。
结语
通过以上讲解,应该对 Axios 有了较为全面的理解。实践是检验学习成果的最佳方式,尝试在项目中应用 Axios,并不断探索其更多高级功能,会逐渐成为 Axios 的高手。如果遇到具体问题,查阅官方文档或寻求社区帮助都是很好的解决途径。
暂无评论内容