一、axios基本概念
1.1 定义
定义
Axios,是一个基于Promise的网络请求库,作用于node.js和浏览器中。
在服务端它使用原生node.js http模块,在客户端(浏览器)使用XMLHttpRequest。
Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中。
原理
axios本质上是对原生XHR的封装,只不过是Promise的实现版本,符合最新的ES规范。
注:XHR 注入技术是通过XMLHttpRequest来获取javascript的。
1.4 安装 Axios
npm install axios
也可直接使用cdn,通过script标签引入。
二、axios 主要特点
- 从浏览器中创建 XMLHttpRequest
- 从node.js创建 http请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求和响应数据
- 取消请求
- 自动转换JSON数据
- 客户端支持防御CSRF(跨域请求伪造)
三、axios 基本使用(常用语法)
3.1 支持箭头函数
(1)普通函数写法
axios.get('./server/user').then(function(response) {
console.log(response)
}).catch(function(error) {
console.log(error)
})
(2)箭头函数写法
axios.get('./server/user').then(response => {
console.log(response)
}).catch(error => {
console.log(error)
})
3.2 常见配置项
- (1)method 创刊请求的方法,默认值get,不区分大小写(也支持axios.get / axios.post 写法)
- (2)url:请求的服务器 URL
- (3)baseURL: 自动添加在 url 前面,除非url是绝对值
- (4)data:请求体用于发送的数据,用于post、put、delete 和 patch 请求方法
- (5)headers:自定义请求头
- (6)params:与请求一起发送的 URL参数,是一个对象
- (7)timeout:指定请求超时毫秒数
示例代码
axios({
// 请求方式,不区分大小写
method: 'post',
// 基础url,最终请求的url是,baseURL+url 拼接
baseURL,
url: 'ABJ?_=',
//请求超时,单位毫秒,默认0,不超时。
timeout: 1000,
//响应数据类型,默认json
responseType: 'json',
//响应数据的编码规则,默认utf-8
responseEncoding: 'utf8',
//响应体的最大长度
maxContentLength: 2000,
// 请求体的最大长度
maxBodyLength: 2000
}).then(response => {
// 正确情况处理
let res = response ? response.data : '';
console.log('正常', res);
}).catch(error => {
// 报错情况处理
let message = error ? error.message : '';
console.log('报错', message)
}).then(() => {
console.log('总是执行');
})
返回体
- config 配置对象
- data 响应体内容
- headers 响应头
- request 发送请求时创建的底层 XMLHttpRequest 对象
- status 状态码
- statusText 状态解析,如 'OK'
3.3 其他常见语法
3.3.1 拦截器(interceptors)
1.请求拦截器(Request Interceptors)
- 真正发送请求前执行的回调函数
- 可对请求进行检查或配置进行特定处理
- 失败的回调函数传递的是 error
- 成功的回调函数传递的是 config(也必须是)
2.响应拦截器(Reponse Interceptors)
- 请求得到响应后执行的回调函数
- 可对响应数据进行特定处理
- 成功的回调函数传递的是 response
- 失败的回调函数,传递的默认是 error
3.拦截器代码示例
import axios from 'axios';
const instance = axios.create({
// 设置 baseURL
baseURL: 'htts://www.aaa.com/api/server/app',
// 设置请求超时
timeout: 2000
});
// 1.添加请求拦截器
instance.interceptors.request.use(
function(config) {
// 在发送前做的事情
// 如,可以添加认证令牌
// 假设token存在 localStorage 中
const token = localStorage.getItem('userToken');
if(token) {
config.headers.Authorization = `Bearer ${token}`
}
// 如果没有返回 config,请求会被拦截器拦截下来,不会发送
return config;
},
function(error) {
// 请求发送错误时,触发的函数
// 可以处理错误,比现实错误信息给用户
return Promise.reject(error)
}
);
// 2.添加响应拦截器
instance.interceptors.response.use(
response => {
// 对响应数据做点什么
// 例如,检查响应中是否有自定义的错误处理
if(response.data.error) {
return Promise.reject(new Error(response.data.error));
}
// 重要的是,需要返回响应对象,否则请求链会中断
return response;
},
error => {
// 对响应错误做点什么
if(error.response) {
// 服务器响应了请求,但返回了错误的 HTTP 状态码
// 可根据不同 status 来处理错误,404 找不到页面,500 服务器内部错误
console.log(`Error Status: ${error.response.status}`);
console.log(error.response.data);
// 可以抛出一个错误,以便在请求的 then 链中捕获
return Promise.reject(error)
}else if(error.request) {
// 请求已发出,但没收到响应
console.log(error.request);
return Promise.reject(error);
} else {
// 设置请求时触发了错误
console.log('Error', error.message);
return Promise.reject(error);
}
// 注意:这里也必须返回一个 Promise 对象,否则请求链会中断
}
);
// 使用实例发送请求
instance.get('./test1').then(
response => {
// 正常情况处理
console.log(response)
}
).catch(
error => {
// 错误情况处理
console.log(error)
}
).then(
// 总是执行
)
export default instance;
3.3.2 转换器
使用 Axios 进行 HTTP 请求时,可能需要对请求的数据或响应的数据进行预处理或后处理。
Axios 提供了请求拦截器和响应拦截器功能,以及通过配置 transformRequest 和 transformResponse 选项来直接转换请求和响应数据。这些功能可以视为“转换器”,它们允许你在数据发送或接收之前对其进行处理。
Axios官方API中没有直接称为 "转换器"(transformers)的功能,但是可以通过拦截器或者直接在请求/响应处理中模拟这一行为。
- 请求转换器: 用于在发送请求前修改请求数据。例如,将JSON对象序列化为JSON字符串、添加一些通用请求头(或自定义请求头)。
- 响应转换器: 用于在接收响应后修改响应数据。例如,将响应体json字符串解析为js对象或数组的函数,转换响应数据的格式以符合应用程序的需求。
实际开发中,需要根据API的特定要求和应用程序的需求来编写这些转换逻辑。
请求转换,示例
// 创建一个 Axios 实例
const axiosInstance = axios.create({
baseURL: 'https://api.example.com',
// 其他配置...
});
// 请求拦截器(请求转换器)
axiosInstance.interceptors.request.use(
config => {
// 假设我们要在发送前将 config.data 转换为 JSON 字符串
// 注意:axios 通常会为你做这件事,但这里只是为了演示
if (config.data && typeof config.data === 'object') {
config.data = JSON.stringify(config.data);
// 设置请求头,告诉服务器我们发送的是 JSON
config.headers['Content-Type'] = 'application/json';
}
// 你可以在这里添加更多的转换逻辑
return config;
},
error => {
// 处理请求错误
return Promise.reject(error);
}
);
// 使用实例发起请求
axiosInstance.post('/some-endpoint', { foo: 'bar' }).then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
响应转换,示例
// 响应拦截器(响应转换器)
axiosInstance.interceptors.response.use(
response => {
// 假设服务器返回了一个包含 data 属性的对象
// 其中 data 是一个 JSON 字符串,我们需要将其解析为 JavaScript 对象
// 但通常,axios 已经为你做了这件事
// 这里只是为了演示如何对响应数据进行进一步处理
if (response.data && typeof response.data === 'string' && response.data.startsWith('{')) {
try {
response.data = JSON.parse(response.data); // 实际上,这一步可能是多余的
} catch (error) {
// 处理 JSON 解析错误
console.error('Error parsing JSON:', error);
}
}
// 你可以在这里添加更多的转换逻辑
return response;
},
error => {
// 处理响应错误
// 例如,检查响应状态码,并相应地处理错误
if (error.response && error.response.status === 404) {
// 处理 404 错误
console.log('Resource not found');
}
return Promise.reject(error);
}
);
3.3.2 使用async/await语法
使用axios库配合 async/await 语法,可以让我们以同步的书写方式写异步代码,能让代码更加清晰易懂。
// 引入axios
const axios = require('axios');
// 异步函数获取数据
async funtion fetchData() {
try {
// 使用axios的get方法请求数据,这里以获取JSONPlaceholder的假数据为例
const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1');
// 响应中获取数据
const data = response.data;
// 可根菌需要对数据进行其他操作
console.log(data);
} catch(error) {
// 处理请求中 可能发生的错误
console.log('There was an error!', error)
}
}
// 调用函数
fetchData();
上述代码:
- fetchData是一个异步函数,使用了 await 关键字来等待 axios.get 请求完成。
- await 只能在函数内部使用,会暂停 async 函数的执行,等待 Promise 解决(resolve)或拒绝(reject),然后才继续执行 async 函数并返回解决的值或抛出拒绝的原因。
- 使用 try...catch 语句来捕获并处理可能发生的任何错误。
- try..catch 是处理异步操作中可能发生的错误的一种常见方式。
注意:在 axios.get 调用前加上 await,意味着JS会在这里暂停执行,直到 axios.get 调用完成(无论成功还是失败),才会继续执行后面的代码。
3.3.3 取消axios请求
Axios的CancelToken是一个用于取消请求的promise。
import axios from 'axios';
// 创建一个CancelToken源
let CancelTokenSource = axios.CancelToken.source();
// 发起一个GET请求
axios.get('/url', {
// 将CancelToken作为请求的配置传入
cancelToken: CancelTokenSource.token
}).then(response => {
console.log(response);
}).catch(error => {
// 检查是否事取消请求的错误
if(axios.isCancel)
})
// 封装取消请求的函数
function cancelRequest(cancelTokenSource) {
if(cancelTokenSource && cancelTokenSource.cancel) {
cancelTokenSource.cancel('取消请求');
}
}
let cancelTokenSource = axios.CancelToken.source();
axios.get('https://jsonplaceholder.typicode.com/todos/1', {
cancelToken: cancelTokenSource.token
}).catch(thrown => {
if(axios.isCancel(thrown)) {
console.log('取消', throwm.message)
} else {
// 错误处理
}
});
// 取消请求
cancelRequest(cancelTokenSource);