有了原生网络请求为什么还需要axios库
- 虽然现代浏览器提供了原生的网络请求API,例如fetch ,XMLHttpRequest,但某些功能不完善, 需要自己封装,
- 于是有了对原生网络请求封装的库axios库,对比下axios具有如下优势:
- 支持所有现代浏览器和旧版浏览器:axios库提供了对浏览器兼容性支持。它使用了一种统一的方式来处理网络请求,不需要考虑底层实现差异 更强大和方便的功能:
- axios封装了对Promise的支持,处理异步操作更方便。如拦截请求和响应、自动转换请求和响应数据、请求取消等。
Vue作者推荐:
axios库功能特点:
补充: axios名称的由来?
个人理解:
- 没有具体的翻译
- axios: ajax i/o system.
AI回答:
- Axios这个名称来源于希腊词语"axios"(ἄξιος),意为"值得的"或"配得上的"。这个名称在英文中常用于表示尊贵、可信赖和高质量的概念。Axios库的创造者Matt
Zabriskie通过选择“Axios”这个名称,来传达一种以优雅、可靠、高质量
的方式处理网络请求的理念- "axios"这个名称既简短而易记
支持多种请求方式:
最常用的是get和put两个请求
- axios(config)
- axios.request(config)
axios.get(url[, config])
- axios.delete(url[, config])
- axios.head(url[, config])
axios.post(url[, data[, config]])
- axios.put(url[, data[, config]])
- axios.patch(url[, data[, config]]
有时候,我们可能需求同时发送两个请求
- 使用axios.all,可以放入多个请求的数组.
- axios.all([])返回的结果是一个数组,使用axios.spread 可将数组[res1,res2]展开为res1, res2
常见的配置选项:
1.安装axios
npm install axios
2.在需要发送网络请求的地方使用axios就可以发送网络请求:
由于开发中最常用的是get和post请求, 下面主要演示get和post请求的使用:
(1)通过request发送get请求:
import axios from 'axios'
// request函数返回一个Promise, 当请求有结果, 内部会自动调用resolve
axios.request({
// 配置请求url地址
url: "http://123.207.32.32:8000/home/multidata",
// 配置请求方式, 不写默认也是get请求
method: "get"
}).then(res => {
// 直接拿到结果是axios默认给我们返回的配置对象
// 如果想单纯拿到服务器的数据需要 .date
console.log(res.data)
})
(2)通过request发送post请求:
import axios from 'axios'
axios.request({
url: "http://123.207.32.32:1888/02_param/postjson",
method: "post",
// 传入请求体
data: {
name: "sevgilid",
password: "aaa123"
}
}).then(res => {
console.log(res.data)
})
(3)通过get函数直接发送get请求
import axios from 'axios'
// get函数传入两个参数, 参数1: url地址, 参数2: 配置信息
axios.get("http://123.207.32.32:9001/lyric", {
// 传入查询字符串
params: { id: 500665346 }
}).then(res => {import axios from 'axios'
// post函数传入三个参数, 第一个url, 第二个请求体, 第三个配置信息
axios.post("http://123.207.32.32:1888/02_param/postjson", {
name: "kaisa",
password: "aaa123"
}).then(res => {
console.log(res.data)
})
console.log(res.data)
})
(4)通过post函数发送post请求
import axios from 'axios'
// post函数传入三个参数, 第一个url, 第二个请求体, 第三个配置信息
axios.post("http://123.207.32.32:1888/02_param/postjson", {
name: "kaisa",
password: "aaa123"
}).then(res => {
console.log(res.data)
})
我们来看如下例子:
在开发中我们
请求的url地址其实前面都是相同的
, 只是后面一部分不相同, 如下:
- 请求地址1: http://123.456.23.23:8000/home/multidata
- 请求地址2: http://123.456.23.23:8000/home/data
- 请求地址3: http://123.456.23.23:8000/about/data
在每次网络请求时, 都写一遍是非常繁琐的, 我们可以通过baseURL将相同的地址抽离
出去
import axios from 'axios'
// 1.抽离到baseURL变量中
const baseURL = "http://123.207.32.32:8000"
// 给axios实例配置公共的基础配置
// 2.配置公共的请求地址baseURL
axios.defaults.baseURL = baseURL
// 补充: 此外还可以配置公共的 超时时间... 等等
axios.defaults.timeout = 10000
// 此时发生请求就不需要传入完整的url
axios.get("/home/multidata").then(res => {
console.log(res.data)
})
我们导入的axios就是默认axios的实例, 既然有了默认的实例为什么要创建axios的实例呢?
一般不会用默认实例,而是为每一个url创建一个实例,不同的url对应不同的实例
当我们从axios模块中导入对象时, 使用的实例是默认的实例;当给该实例设置一些默认配置时, 这些配置就被固定下来了.
但是后续开发中, 某些配置可能会不太一样, 比如
某些请求需要使用特定的baseURL或者timeout等
.这个时候, 我们就可以创建新的实例, 并且传入属于当前实例的配置信息.
好处:如果
有多个不相同的配置, 我们可以创建多个实例单独为每个实例进行配置
, 当需要哪一个实例, 就调用哪一个实例,实例之间的配置信息互不影响
// axios创建实例好处:
// -如与多个服务器进行沟通,不止一个实例
// -实例设置一些默认配置时, 这些配置就被固定;如timeout这些
// crete函数创建axios实例
const instance1 = axios.create({
// 创建axios实例可以进行公共的配置信息, 且这些配置只针对当前实例
baseURL: "http://123.207.32.32:9001",
timeout: 6000,
headers: {}
})
// 当baseURL的请求地址不一样时, 可以再创建一个实例
const instance2 = axios.create({
baseURL: "http://123.207.32.32:8000",
timeout: 10000
})
// 实例1发送网络请求
instance1.get("/lyric", {
params: {
id: 500665346
}
}).then(res => {
console.log(res.data)
})
// 实例2发送网络请求
instance2.get("/home/multidata").then(res => {
console.log(res.data)
})
- 使用
axios.all
, 可以放入多个请求的数组;- axios.all([]) 返回的结果是一个数组,使用
axios.spread
可将数组 [res1,res2] 展开为 res1, res2;- 当数组中的请求都有结果是时,才会返回结果;
import axios from 'axios'
// 同时发生多个网络请求
axios.all([
axios.get("/home/multidata"),
axios.get("http://123.207.32.32:9001/lyric?id=500665346")
]).then(res => {
console.log(res)
})
axios的也可以设置拦截器, :拦截每次请求和响应
1.请求拦截格式: axios.interceptors.request.use(请求成功回调拦截, 请求失败回调拦截)
- 会将配置信息config传给回调函数, 我们可以通过config修改当次请求的配置信息, 修改完成后我们需要将返回return config
- 请求失败拦截, 会将错误信息err传给回调函数
import axios from 'axios'
axios.interceptors.request.use((config) => {
console.log("请求成功的拦截, 可以通过config修改配置信息")
// 修改了配置信息需要再将配置信息返回出去
return config
}, (err) => {
console.log("请求失败的拦截")
return err
})
2.响应拦截格式: axios.interceptors.response.use(响应成功回调拦截, 响应失败回调拦截)
- 响应成功拦截, 会将请求成功的数据传给成功的回调函数
- 我们前面说过axios的请求结果, 会默认会返回一个配置对象, 响应拿到服务器的数据需要 .data 才可以获取, 其实这一转换操作, 我们可以在响应拦截中完成
3.请求和响应拦截常见操作
- 在
请求拦截的成功拦截
中:一般会修改一些配置信息,如header,认证登录的token/cookie,转化某些参数
再返回;开始loading加载动画- 在
响应拦截的成功拦截
中:结束拦截动画;拿到服务器数据转化(res.data)
这样
axios非常好用, 当我们在多个组件中需要发生网络请求的时候, 多个组件都需要导入axios实例, 再通过axios实例发送网络请求
这样的用法是没有问题的。那么我们为什么还要对axios进行封装呢?
但是axios毕竟是一个第三方的库, 不是官方维护的, 如果有一天axios不再进行维护了, 我们项目中使用axios的地方都需要重构, 这个工程量是非常大的, 修改起来也非常不方便。
那么解决方案是: 我们使用axios封装一个自己的request函数, 当axios真的不再维护, 我们修改代码时, 只需要修改自己封装的函数即可, 这样重构代码会非常简单
封装源码:
import axios from 'axios'
class MyRequest {
constructor(baseURL, timeout=10000) {
this.instance = axios.create({
baseURL,
timeout
})
}
//使用this来指向当前创建的实例对象
//1.封装request
request(config) {
// 返回一个Promise, 对数据转换
return new Promise((resolve, reject) => {
this.instance.request(config).then(res => {
resolve(res.data)
}).catch(err => {
reject(err)
})
})
}
//2.封装get
get(config) {
return this.request({ ...config, method: "get" })
}
//3.封装post
post(config) {
return this.request({ ...config, method: "post" })
}
//后面也可以在这里创建更多的方法,方式是差不多的
}
export default new MyRequest()
//这里导出的是一个实例对象,然后你也可以创建多个实例对象导出去,这个就是比较简单了