1. axios是什么
(1)前端最流行的ajax请求库
(轻量级)
(2)react/vue官方都推荐使用axios发ajax请求
(3)文档:https://github.com/axios/axios
2. axios特点
(1)基于promise的异步ajax请求库 (执行完请求后返回的是promise对象)
(2)浏览器端/node端都可以使用
(3)支持请求/响应拦截器 (拦截器是统一对响应和请求做处理的函数)
(4)支持请求取消
(5)请求/响应数据转换
(6)批量发送多个请求
3. axios常用语法
(1)axios(config): 通用/最本质的发任意类型请求的方式
(2)axios(url[, config]): 可以只指定url发get请求
(3)axios.request(config): 等同于axios(config)
(4)axios.get(url[, config]): 发get请求
(5)axios.delete(url[, config]): 发delete请求
(6)axios.post(url[, data, config]): 发post请求
(7)axios.put(url[, data, config]): 发put请求
(8)axios.default.xxx: 请求的默认全局配置
(9)axios.interceptors.request.use(): 添加请求拦截器
(10)axios.interceptors.response.use(): 添加响应拦截器
(11)axios.create([config]): 创建一个新的axios(它没有下面的功能)
(12)axios.Cancel(): 用于创建取消请求的错误对象
(13)axios.CancelToken(): 用于创建取消请求的token对象 (cancelToken在axios@0.22.0后弃用了)
(14)axios.isCanel(): 是否是一个取消请求的错误
(15)axios.all(promise): 用于批量执行多个异步请求
(16)axios.spread(): 用来指定接收所有成功数据的回调函数的方法
示例代码如下👇
<body>
<div>
<button onclick="testGet()">GET请求</button>
<button onclick="testPost()">POST请求</button>
<button onclick="testPut()">PUT请求</button>
<button onclick="testDelete()">DELETE请求</button>
</div>
<script src="https://cdn.bootcss.com/axios/0.19.0/axios.min.js"></script>
<script>
// 指定默认配置路径
axios.defaults.baseURL = 'http://localhost:3000'
// GET请求:从服务器端获取数据
function testGet () {
axios({
url: '/posts',
method: 'GET',
params: {
id: 1
}
}).then(
response => {
console.log('/posts get', response.data)
})
}
// POST请求:服务器端保存数据
function testPost () {
axios({
url: '/posts',
method: 'POST',
data: {
"title": "json-server!!!",
"author": "typicode!!!"
}
}).then(
response => {
console.log('/posts post', response.data)
})
}
// PUT请求:服务器端更新数据
function testPut () {
axios({
url: '/posts/1',
method: 'PUT',
data: {
"title": "json-server~~~",
"author": "typicode~~~"
}
}).then(
response => {
console.log('/posts put', response.data)
})
}
// DELETE请求:服务器端删除数据
function testDelete () {
axios({
url: '/posts/2',
method: 'DELETE'
}).then(
response => {
console.log('/posts delete', response.data)
})
}
</script>
</body>
如果运行失败,在终端输入如下命令再刷新查看是否请求成功
json-server --watch db.json
4. 难点语法的理解和使用
(1)axios.create(config)
- 根据指定配置创建一个新的axios,也就是每个新的axios都有自己的配置
- 新的axios只是没有取消请求和批量发请求的方法,其它所有语法都是一致的
- 设计该语法是为了处理项目中有部分接口需要的配置与另一部分接口需要的配置不一样;通过创建2个新axios,每个都有自己特有的配置,分别
应用到不同要求的接口请求中
即可解决
<body>
<script src="https://cdn.bootcss.com/axios/0.19.0/axios.min.js"></script>
<script>
axios.defaults.baseURL = 'http://localhost:3000'
// 使用axios发请求
axios({
url: '/posts' // 请求3000
})
const instance = axios.create({
baseURL: 'http://localhost:4000'
})
instance.get('/xxx')
</script>
</body>
(2)拦截器函数/ajax请求/请求
<body>
<script>
// 添加请求拦截器(回调函数)——后添加先执行
// 第一种形式
axios.interceptors.request.use(
config => {
console.log('request interceptor1 onResolved()')
return config; // 如果不设置返回config,会报错cancelToken,控制台提示undefined
},
error => {
console.log('request interceptor1 onRejected()')
return Promise.reject(error);
}
)
// 第二种形式
axios.interceptors.request.use(
function (config) {
console.log('request interceptor2 onResolved()')
return config;
},
function (error) {
console.log('request interceptor2 onRejected()')
return Promise.reject(error);
}
);
// 添加响应拦截器
// 第一种形式
axios.interceptors.response.use(
response => {
console.log('response interceptor1 onResolved()')
return response // 如果不设置返回response,会报错data,控制台提示undefined
},
error => {
console.log('response interceptor1 onRejected()')
return Promise.reject(error);
}
)
// 第二种形式
axios.interceptors.response.use(
function (response) {
console.log('response interceptor2 onResolved()')
return response;
},
function (error) {
console.log('response interceptor2 onRejected()')
return Promise.reject(error);
}
);
axios.get('http://localhost:/posts')
.then(response => {
console.log('data', response.data)
})
.catch(error => {
console.log('error', error.message)
})
</script>
</body>
该流程是通过promise串联起来的,请求拦截器传递的是config,响应拦截器传递的是response👆
(3)取消请求
先创建server.js文件,文件代码如下👇
// server.js
const express = require('express')
const cors = require('cors')
const app = express()
// 使用cors,允许跨域
app.use(cors())
// 能解析urlencode格式的post请求体参数
app.use(express.urlencoded())
// 能解析json格式的请求体参数
app.use(express.json())
app.get('/products1', (req, res) => { // 注册的第一个路由
setTimeout(() => {
res.send({
{id: 1, name: 'product1.1'},
{id: 2, name: 'product1.2'},
{id: 3, name: 'product1.3'},
})
}, 1000 + Math.random()*2000);
})
app.get('/products2', (req, res) => { // 注册的第二个路由
setTimeout(() => {
res.send({
{id: 1, name: 'product2.1'},
{id: 2, name: 'product2.2'},
{id: 3, name: 'product2.3'},
})
}, 1000 + Math.random()*2000);
})
app.listen(4000, () => {
console.log('server app start on port 4000')
})
在终端运行如下命令👇
node server.js
再创建一个新的html文件👇
<body>
<button onclick="getProducts1">获取商品列表1</button>
<button onclick="getProducts1">获取商品列表1</button>
<button onclick="cancelReq">取消请求</button>
<script>
let cancel // 用于保存取消请求的函数
function getProducts1() {
axios({
url: 'http://localhost:4000/products1',
cancelToken: new axios.CancelToken((c) => { // c是用于取消当前请求的函数
// 保存取消函数, 用于之后可能取消当前请求
cancel = c
})
}).then(
response => {
cancel = null
console.log('请求1成功', response.data)
},
error => {
cancel = null
console.log('请求1失败', error.message, error)
})
}
function getProducts2() {
axios({
url: 'http://localhost:4000/products2'
}).then(
response => {
cancel = null
console.log('请求2成功', response.data)
},
error => {
cancel = null
console.log('请求2失败', error.message, error)
})
}
function cancelReq() {
// 执行取消请求的函数
if (typeof cancel === 'function') {
cancel('强制取消请求')
} else {
console.log('没有可取消的请求')
}
}
</script>
</body>
对取消请求的功能再进行优化,实现点击新的请求时取消前面的请求👇
<body>
<button onclick="getProducts1">获取商品列表1</button>
<button onclick="getProducts2">获取商品列表2</button>
<button onclick="cancelReq">取消请求</button>
<script src="https://cdn.bootcss.com/axios/0.19.0/axios.min.js"></script>
<script>
let cancel // 用于保存取消请求的函数
function getProducts1 () {
// 在准备发请求前,取消未完成的请求
if (typeof cancel === 'function') {
cancel('取消请求')
}
axios({
url: 'http://localhost:4000/products1',
cancelToken: new axios.CancelToken((c) => { // c是用于取消当前请求的函数
// 保存取消函数, 用于之后可能取消当前请求
cancel = c
})
}).then(
response => {
cancel = null
console.log('请求1成功', response.data)
},
error => {
if (axios.isCancel(error)) {
console.log('请求1取消的错误', error.message)
} else {
cancel = null
console.log('请求1失败', error.message)
}
})
}
function getProducts2 () {
// 在准备发请求前,取消未完成的请求
if (typeof cancel === 'function') {
cancel('取消请求')
}
axios({
url: 'http://localhost:4000/products2',
cancelToken: new axios.CancelToken((c) => { // c是用于取消当前请求的函数
// 保存取消函数, 用于之后可能取消当前请求
cancel = c
})
}).then(
response => {
cancel = null
console.log('请求2成功', response.data)
},
error => {
if (axios.isCancel(error)) {
console.log('请求2取消的错误', error.message)
} else { // 请求出错了
cancel = null
console.log('请求2失败', error.message)
}
})
}
function cancelReq () {
// 执行取消请求的函数
if (typeof cancel === 'function') {
cancel('强制取消请求')
} else {
console.log('没有可取消的请求')
}
}
</script>
</body>
代码重复高👆
通过设置拦截器,降低代码重复👇
<body>
<button onclick="getProducts1">获取商品列表1</button>
<button onclick="getProducts2">获取商品列表2</button>
<button onclick="cancelReq">取消请求</button>
<script src="https://cdn.bootcss.com/axios/0.19.0/axios.min.js"></script>
<script>
// 添加请求拦截器
axios.interceptors.request.use((config) => {
// 在准备发请求前,取消未完成的请求
if (typeof cancel === 'function') {
cancel('取消请求')
}
// 添加一个cancelToken的配置
config.cancelToken = new axios.CancelToken((c) => { // c是用于取消当前请求的函数
// 保存取消函数, 用于之后可能取消当前请求
cancel = c
})
})
// 添加响应拦截器
axios.interceptors.response.use(
response => {
cancel = null
return response
},
error => {
if (axios.isCancel(error)) { // 取消请求的错误
console.log('请求取消的错误', error.message) // 做相应处理
// 中断promise链接
return new Promise(() => { })
} else { // 请求出错了
cancel = null
// 将错误向下传递
return Promise.reject(error)
}
}
)
let cancel // 用于保存取消请求的函数
function getProducts1 () {
axios({
url: 'http://localhost:4000/products1'
}).then(
response => {
console.log('请求1成功', response.data)
},
error => { // 只用处理请求失败的情况,取消请求的错误的不用
console.log('请求1失败', error.message)
}
)
}
function getProducts2 () {
axios({
url: 'http://localhost:4000/products2'
}).then(
response => {
console.log('请求2成功', response.data)
},
error => {
console.log('请求2失败', error.message)
}
)
}
function cancelReq () {
// 执行取消请求的函数
if (typeof cancel === 'function') {
cancel('强制取消请求')
} else {
console.log('没有可取消的请求')
}
}
</script>
</body>