文章目录
一、前言
Vue中发送网络请求有非常多的方式, 那么在开发中, 如何选择呢?
1、我们经常会使用jQuery-Ajax(相对于传统的Ajax非常好用),为什么不选择它呢?
- 首先, 我们先明确一点: 在Vue的整个开发中很少使用jQuery了
- 那么为了方便我们进行一个网络请求, 特意引用一个jQuery, 不太合理
- jQuery的代码1w+行,Vue的代码才1w+行
- 所以完全没有必要为了用网络请求就引用这个重量级的框架
2、官方在Vue1.x的时候, 推出了Vue-resource,Vue-resource的体积相对于jQuery小很多,另外Vue-resource是官方推出的。为什么不选择它呢?
- 在Vue2.0推出后, Vue作者就在GitHub的Issues中说明了去掉vue-resource, 并且以后也不会再更新
- 那么意味着以后vue-reource不再支持新的版本时, 也不会再继续更新和维护
- 对以后的项目开发和维护都存在很大的隐患
3、使用 axios
vue作者在说明不再继续更新和维护vue-resource的同时,推荐了一个框架: axios
二、axios介绍
axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范。axios设计简洁,API简单,支持浏览器和node
功能特点:
- 在浏览器中发送 XMLHttpRequests 请求
- 支持在 node.js 中发送 http请求
- 支持 Promise API
- 拦截请求和响应
- 自动转换 JSON 数据
- 转换请求和响应数据,等等
支持多种请求方式:
- 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]])
三、安装
在vue中使用,我用vue-cli创建了一个项目来演示。在本博客底部有演示代码的下载链接,供学习交流。
npm install axios --save
四、基本使用
1、发送get请求
(1)使用 axios(config)
,它默认发送 get 请求
axios({
url: '127.0.0.1:8000',
//拼接参数
params: {
name: 'webchang',
page: 1
},
}).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
注意:因为 axios 是基于Promise的,所以执行 axios({ url: 'xxx' })
会返回一个 Promise,如果成功拿到数据,会在内部调用resolve,所以我们可以在它后边加 then() 方法。
(2)使用 axios.get(url[, config])
,不带参数
axios.get('http://127.0.0.1:8000')
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
})
(3)使用 axios.get(url[, config])
,带参数
axios.get('http://127.0.0.1:8000', {
params: {
name: 'webchang',
page: 1
}
}).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
对于 get 请求,我们也可以直接把参数拼接到 url 的后边
axios.get('http://127.0.0.1:8000?name=webchang')
axios请求的响应包含以下信息:
{
// `data` 由服务器提供的响应
data: {
},
// `status` HTTP 状态码
status: 200,
// `statusText` 来自服务器响应的 HTTP 状态信息
statusText: "OK",
// `headers` 服务器响应的头
headers: {
},
// `config` 是为请求提供的配置信息
config: {
}
}
2、发送post请求
(1)使用 axios(config)
,我们可以指定它的 method 为 post
axios({
url: '127.0.0.1:8000',
method: 'post',
data: {
// post请求的参数要用 data传递
firstName: 'Fred',
lastName: 'Flintstone'
}
}).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
(2)使用 axios.post(url[, config])
axios.post('/user', {
firstName: 'Fred', //参数
lastName: 'Flintstone' //参数
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
3、发送并发请求
有时候, 我们可能需求同时发送多个请求,在多个请求都拿到数据后再进行处理。我们可以使用 axios.all()
axios.all([ ])的参数是一个数组,每个数组元素是一个请求。返回的结果也是一个数组,每个元素都是请求的结果。
axios.all([
axios({
url: 'http://127.0.0.1:8000/home/multidata'
}),
axios({
url: 'http://127.0.0.1:8000/api/w6/home/data',
params: {
type: 'sell',
page: 1
},
})
]).then(res => {
console.log(res[0]); //res 是一个数组,存放每个请求的数据
console.log(res[1]);
}).catch(err => {
console.log(err);
})
使用 axios.spread
可将结果数组 [res1,res2] 展开为 res1, res2
axios.all([
axios({
url: 'http://127.0.0.1:8000/home/multidata'
}),
axios({
url: 'http://127.0.0.1:8000/home/data',
params: {
type: 'sell',
page: 1
},
})
]).then(axios.spread((res1,res2) => {
console.log(res1); //res1是第一个请求的结果
console.log(res2); //res2是第二个请求的结果
})).catch(err => {
console.log(err);
})
4、全局配置
在上面的示例中, 我们的baseURL是固定的,事实上, 在开发中可能很多参数都是固定的。这个时候我们可以进行一些抽取, 也可以利用axiox的全局配置
axios.defaults.baseURL = 'http://127.0.0.1:8000'
axios.defaults.timeout = 5000
axios({
url: '/home/data', // url的前边就可以省略baseUrl
params: {
type: 'sell',
page: 1
}
}).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
5、创建axios的实例
当我们从axios模块中导入对象时, 使用的实例是默认的实例。当给该实例设置一些默认配置时, 这些配置就被固定下来了。就像上边代码中使用的那样。
但是后续开发中, 某些配置可能会不太一样,比如某些请求需要使用特定的baseURL或者timeout或者content-Type等。这个时候, 我们就可以使用 axios.create([config])
创建新的实例, 并且传入属于该实例的配置信息。
//创建新的axios实例,为该实例设置特定的 baseUrl等配置
const axiosInstance = axios.create({
baseURL: 'http://127.0.0.1:8000',
timeout: 5000
})
// 使用实例发送网络请求,默认为 get请求
axiosInstance({
url:'/home/multidata'
}).then(res => {
console.log(res);
})
五、模块封装
进行网络请求时,即使我们选择了一个第三方框架axios,也尽量对其进行再次封装。不直接使用第三方框架进行网络请求,而是使用我们封装好的一个模块去进行网络请求。为什么呢?
因为假如说第三方的框架在某一天突然就不维护了,或者出现了严重的bug,严重的漏洞,这其实是一件非常危险的事情。在这种情况下,如果我们的应用程序里边直接对这个第三方框架的依赖性很强,这个时候再去换框架,就是一件非常麻烦的事情。所以我们最好对第三方框架再进行一个封装,而不是直接在项目中使用它。
我们可以创建一个network文件夹,在文件夹中创建request.js文件
import axios from "axios";
export function request(config) {
const instance = axios.create({
baseURL: 'http://xxx',
timeout: 5000
})
return instance(config)
}
使用:
import {
request} from '../network/request'
request({
url: '/home/multidata'
}).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
虽然只是封装一下多了几行代码,但是却极大的减少了项目对axios的依赖。如果某一天项目不准备用axios了,只需改动 request.js
六、使用拦截器
axios提供了拦截器,用于我们在发送每次请求或者得到相应后,进行对应的处理。
如何使用拦截器呢?
export function request(config) {
//1.创建axios的实例
const instance = axios.create({
baseURL: 'http://152.136.185.210:8000/api/w6',
timeout: 5000
})
//2.axios的拦截器
//拦截请求
instance.interceptors.request.use(config => {
console.log('拦截请求成功',config);
return config;
},err => {
//可能的错误比如请求超时,可以将页面跳转到一个错误页面中。
console.log('拦截请求失败');
return err;
})
//拦截相应
instance.interceptors.response.use(response => {
console.log('拦截相应成功',response);
//对数据进行过滤
return response.data;
},err => {
console.log('拦截相应失败');
return err;
})
return instance(config)
}
拦截请求的场景:
- 请求中的一些信息不符合服务器的要求,要先进行处理
- 每次发送网络请求时,都希望在界面中显示一个请求的图标
- 某些网络请求(比如登录),必须携带一些特殊的信息(token)
拦截相应的场景:
-
响应的成功拦截中,主要是对数据进行过滤。
-
响应的失败拦截中,可以根据status判断报错的错误码,跳转到不同的错误提示页面。
七、资料
https://gitee.com/mirrors/axios/tree/v0.20.0/
本博客演示代码的下载链接:https://webchang.lanzous.com/ikbe5knbkwb 密码:db81