常见的网络请求模块, 以及它们的优缺点对比
- 传统Ajax请求
- 缺点: 配置和调用方式等非常混乱
- 真实开发中真的很少直接使用, 而是使用Jquery-Ajax
- Jquery-ajax
- 相对于传统的Ajax非常好用
- 但是我们在整个vue的开发中都是不需要使用Jquery的
- 那么就意味着为了方便我们进行一个网络请求, 特意引用了一个jQuery, 这显然不合理, Vue的代码才一万多行, jQuery的代码就一万多行了
- 完全没有必要为了使用网络请求就引用jQuery这个框架
- 官方在Vue1.x的时候, 推出了Vue-resource
- Vue-resource的体积相对于jQuery小很多
- 而且Vue-resource是Vue官方推出的
- 但是在Vue2.0以后, Vue-resource就不再更新了
- 这就意味着如果继续使用Vue-resource的话对项目的开发和维护都存在很大的隐患
- axios
- 在尤雨溪宣布不再更新vue-resource的时候, 推荐使用axios
- 所以就选axios了
- vue作者都让你选这个了, 你还想啥呢?
- 可能你会说, 尤雨溪只是个写轮子的, 他懂个P的vue(/滑稽)
axios的基本使用
- 安装axios 在项目根目录下, 命令行输入
- npm install axios --save (运行时依赖)
- 导入axios, 直接通过 axios() 使用, 并不需要使用Vue.use(axios) 来install, 因为axios本身并不是vue中的模块, vue并不具有axios的install方法
- axios支持多种请求方式
- 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(config) 因为这个灵活, 可以在config里面设置请求方式
- axios的特点: axios() 在网络请求完成后会返回一个Promise对象, 所以我们可以在axios() 后直接使用then() 和catch()
- 请看下列代码实例
import axios from "axios"
axios({
url : "请求的url",
method : "post",
params : {
type : "pop",
page : 1
}
}).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
})
axios处理并发请求
- 如果我们需要多个axios请求完成后, 再进行下一步的操作
- axios提供了一个 axios.all() 方法, 用于处理这种需求
- 这个方法里面传入一个数组, 数组中传入axios请求
- 在axios请求都完成后, axios.all() 方法会调用then(), then()中传入一个函数, 函数中有一个result参数
- result是一个数组, 数组中第一个数据即是第一个axios请求返回的数据, 依此类推
- 如果想要将各个返回的数据分开的话, then() 中还可以传入一个 axios.spread() 方法, 方法中传入一个函数
- 该函数的参数就是对应的axios请求返回的数据
- 看以下实例代码
import axios from "axios"
axios.all([
axios({
url : ""
}),
axios({
url : "",
params : {
type : "pop",
page : 5
}
})
])
.then(axios.spread((res1, res2)=> {
console.log(res1);
console.log(res2);
}))
.catch(err => {
console.log(err);
})
axios设置全局配置信息
- 其实我们的请求中有很多东西都是相同的, 比如url中的baseURL, 和设置的请求超时时间等等
- 如果我们每次请求都要重写这些config, 这样代码就很重复了
- 所以我们会将固定的参数抽取出来
- axios提供了一个 defaults 对象用于进行全局配置
- 看以下代码实例
import axios from "axios";
axios.defaults.baseURL = ""
axios.defaults.timeout = 5000
axios.all([
axios({
url : "/home/multidata"
}),
axios({
url : "/home/data",
params : {
type :"pop",
page : 2
}
})
]).then(axios.spread((res1, res2)=> {
console.log(res1);
console.log(res2);
}))
.catch(err => {
console.log(err);
})
常见的axios配置项
- 请求地址
- 请求类型
- 请根路径
- baseURL: ‘http://www.mt.com/api’,
- 请求前的数据处理
- transformRequest:[function(data){}],
- 请求后的数据处理
- transformResponse: [function(data){}],
- 自定义的请求头
- headers:{‘x-Requested-With’:‘XMLHttpRequest’},
- URL查询对象 (注意只有get请求方式才用params)
- 查询对象序列化函数
- paramsSerializer: function(params){ }
- request body (注意只用post请求方式才用这个)
- 超时设置s
- 跨域是否带Token
- 自定义请求处理
- adapter: function(resolve, reject, config){},
- 身份验证信息
- auth: { uname: ‘’, pwd: ‘12’},
- 响应的数据格式 json / blob /document /arraybuffer / text / + stream
创建axios实例
- 在实际开发中, 很有可能会遇到这种状况
- 网络请求的baseURL是不一样的, 或者说不同的网络请求设置的请求超时时间是不一样的
- 这个时候, 如果我们还是使用全局配置的 axios.default 就无法正确地请求正确的数据了
- 所以我们要创建axios实例
- 创建axios实例, 通过axios.create创建
- 看以下代码实例
const instans1 = axios.create({
baseURL : "",
timeout : 5000
})
instans1({
url : "/home/multidata"
}).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
const instans2 = axios.create({
baseURL : "",
timeout : 10000
})
instans2({
url : "/home/data",
params : {
type :"pop",
page : 2
}
}).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
axios的封装
- 如果我们没有把axios封装到一个文件中, 而是在需要用到axios的组件中都引用axios
- 那么如果在未来的某一天, axios突然宣布不再更新
- 那我们的项目想要使用另外的替代品将会变得十分困难, 因为我们每个组件都依赖了axios
- 为了降低我们各个组件对axios的依赖性
- 我们要将axios封装在一个独立的文件中
- 封装过程及引用方法请看下列示例代码
import axios from "axios"
export function request(config) {
const instans = axios.create({
baseURL : "",
timeout : 5000
})
instans(config)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
})
}
import request from "./network/request"
request({
url : "/home/multidata"
})
export function request(config,success,error) {
const instans = axios.create({
baseURL : ""
})
instans(config)
.then(res => {
success(res)
})
.catch(err => {
error(err)
})
}
import request from "./network/request"
request(
{
url: "/home/multidata",
},
(res) => {
console.log(res);
this.res = res;
}
);
export function request(config) {
const instans = axios.create({
baseURL : ""
})
instans(config.baseConfig)
.then(res => {
config.success(res)
})
.catch(err => {
config.error(err)
})
}
request({
baseConfig: {
url: "/home/multidata",
},
success: function (res) {
console.log(res);
},
error: function (err) {
console.log(err);
},
});
export function request(config) {
const instans = axios.create({
baseURL : ""
})
return new Promise((resolve, reject) => {
instans(config)
.then((res) => {
resolve(res)
})
.catch(err => {
reject(err)
})
})
}
request({
url: "/home/multidata",
})
.then((res) => {
this.res = res;
})
.catch((err) => {
console.log(err);
});
export function request(config) {
const instans = axios.create({
baseURL : ""
})
return instans(config)
}
request({
url: "/home/multidata",
})
.then((res) => {
this.res = res;
})
.catch((err) => {
console.log(err);
});
axios拦截器的使用
- axios提供了拦截器, 用于我们再发送每次请求或者得到相应数据后, 进行对应的处理
- 拦截器分为: 请求拦截器 interceptors.request 和 响应拦截器 interceptors.response
- 请求拦截器主要用法
- 1.当发送网络请求的时候, 在页面中添加一个loading组件, 作为动画
- 2.某些请求是要求用户必须登陆的, 这是请求拦截器就可以判断请求是否带有token(令牌), 如果没有token就跳转到login页面
- 3.对请求的参数进行序列化, 就是对请求的参数做一些修改或者添加一些参数
- 响应拦截器主要用法
- 1.响应的成功拦截中,主要是对数据进行过滤
- 2.响应失败的拦截中, 跨域根据status判断报错的错误码, 跳转到不同的错误提示页面
- 拦截器使用注意事项, 使用拦截器后, 一定要将数据 return 出去, 否则, 拦截器会把数据拦截住
- 基本使用方法看下列代码
export function request(config) {
const instans = axios.create({
baseURL : ""
})
instans.interceptors.request.use(config => {
console.log(config);
return config
}, err => {
console.log(err);
})
instans.interceptors.response.use(res => {
console.log(res);
return res.data
}, err => {
console.log(err);
})
return instans(config)
}