什么是axios
Axios 是一个基于 promise 的 HTTP 库,用于浏览器和node.js等http客户端,主要用来向后台发送各种业务请求和特殊处理,由于axios支持后台数据交互、拦截请求和响应、取消请求、超时设定、转换json、防御XSRF攻击等特性,Vue官方已经不再维护vue-resource并且推荐使用axios。
我们都知道在Vue中要频繁的和后台进行数据交互,所以对数据的处理是很关键的一步,不仅需要方便简洁的请求操作,更需要确保数据安全,所以axios当之无愧的成为Vue的首选。
axios使用
安装axios,进入项目文件夹打开cmd,输入,然后在main.js中全局引入axios,之后在组件中调用即安装axios,进入项目文件夹打开cmd,输入,然后在main.js中全局引入axios,之后在每个用到的组件中调用。
#安装axios
npm install --save axios
#main.js全局引入
import axios from 'axios'
import qs from 'qs'
Vue.prototype.$axios = axios
Vue.prototype.$qs = qs
#组件中使用
this.$axios.get(url,params).then(res=>{
console.log(res.data)
}).catch(console.log(error))
为什么要二次封装
1,代码封装,重用性高,减少代码量,降低维护难度。
2,统一处理一些常规的问题一劳永逸,如http错误。
3,拦截请求和响应,提前对数据进行处理,如获取token,修改配置项。
如何二次封装
在src目录中新建一个api文件夹,在里面新增api.js和axios.js两个文件,api.js用来统一管理api接口,而axios则用来二次封装axios(以上是我个人的方案,如果你觉得更好的方案可以忽略)。
引入组件
在axios.js中引入相应的组件,qs模块,用来序列化post类型的数据,element-ui提示框组件用来弹出提示信息,store用来获取用户的token信息。
import axios from 'axios' // 引入axios
import qs from 'axios'// 引入qs模块,用来序列化post类型的数据
import {Message} from 'element-ui' //引入element-ui提示框框组件
import store from 'store' //引入store
设置请求超时、基本路由和post请求头
通过axios.defaults.timeout可以设置默认的请求超时时间,当数据请求时间超过该设定时间时终止请求,这里我设置了5秒。之前我们在发送post的请求时发现,Vue默认的请求头是
application/x-www-form-unlencoded,这种方式Django后台无法接受到数据,所以我这直接给axios重新定义请求头为Content-Type:
application/x-www-form-urlencoded。axios.defaults.baseURL可以用来设置基本路由,方便统一设置服务器域名。
参考:Vue实战032:axios使用get和post发送各种请求
axios.defaults.baseURL = 'http://127.0.0.1:8000/' //我是用djando搭建的后台
axios.defaults.timeout = 5000;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
请求拦截
顾名思义,就是在发送业务请求前进行阻拦,阻拦的目的是在数据发送前对数据进行一定逻辑的处理,比如统一添加token,当然前提是我们在登录的时候将token通过localStorage或者cookie存在本地并更新至store中,然后每次发送请求的时候就去store中提取对应的token赋给header,后台通过token来判断用户是否登录。
// 请求拦截器(请求发出前处理一些请求)
axios.interceptors.request.use(
config => {
// 每次发送请求之前判断store中是否存在token,然后将token放入header,这样就不用每次请求时都手动添加token了const token = store.state.token;
token && (config.headers.Authorization = token);
return config;
},
error => {
return Promise.error(error);
})
响应拦截
当axios拿到服务器返回给我们的数据,对数据进行一些统一的处理,这里主要针对异常处理,如果后台返回的状态码是200,则正常返回数据,如果请求失败,那么我们就可以根据错误的状态码类型进行一些常规的异常处理方案。
// 响应拦截器(处理响应数据)
axios.interceptors.response.use(
response => {
if (response.data.code === 200) {
return Promise.resolve(response)
} else {
return Promise.reject(response)
}
},
error => {
let status = error.response.data.code
if (code) {
switch (code) {
case 401:
// 跳转登录页面并将要浏览的页面fullPath传过去this.$router.replace({
path: '/login',
query: { redirect: this.$router.currentRoute.fullPath }
})
break
case 500:
//* ****省略*** */
break
default:
Message.error(error.response.data.message)
break
}
return Promise.reject(error.response)
}
}
)
封装post、 get 、put 、delete方法
接下来我们可以来封装一些常用的请求方法,在项目中我们比较常用的方法有post、 get 、put 、delete,接下来我们对这几个方法进行二次封装,将url和header进行封装,这样在使用的时候我们只需要调用接口函数以及传入params即可。这里我统一返回了res.data,所以在获取数据的时候注意下层次,最好用console.log打印下获取的数据,别拿错了数据。
封装get/delete方法
定义一个get/del函数,传递有两个参数,参数1url地址,参数2携带的请求参数。然后返回一个promise对象,请求成功时resolve服务器返回 值,请求失败时reject错误。
// 封装get请求
function get (url, params) {
return new Promise((resolve, reject) => {
axios.get(url, {
params: params
}).then(res => {
resolve(res.data)
}).catch(err => {
reject(err.data)
})
})
}
// 封装delete请求
function del (url, params) {
return new Promise((resolve, reject) => {
axios.delete(url, {
params: params
}).then(res => {
resolve(res.data)
}).catch(err => {
reject(err.data)
})
})
}
封装post/put方法
post需要注意的就是需要对参数进行序列化操作,否则后台是拿不到你提交的数据,axios中提供了qs模块,可以对参数进行序列化,在axios中引入this.$qs.stringify(),这样在传参前将数据自动处理成键值对形式,这里我们可以看到发送的数据格式为Form Data(请求头 Content-Type:
application/x-www-form-urlencoded),后台也正常接收到了数据。
// 封装post请求
function post (url, params) {
return new Promise((resolve, reject) => {
axios.post(url, qs.stringify(params))
.then(res => {
resolve(res.data)
}).catch(err => {
reject(err.data)
})
})
}
// 封装put请求
function put (url, params) {
return new Promise((resolve, reject) => {
axios.put(url, qs.stringify(params))
.then(response => {
resolve(response.data)
}).catch(err => {
reject(err)
})
})
}
抛出方法
最后我们写个导出函数,将方法抛出去,这样其他组件就可以访问到我们封装的方法了,通过提交的方法来判断我们该调用哪个方法。
// 抛出函数,对外的接口
export default function request (method, url, params) {
if (method === 'get') {
return get(url, params)
} else if (method === 'delete') {
return del(url, params)
} else if (method === 'post') {
return post(url, params)
} else if (method === 'put') {
return put(url, params)
}
}
全局注册
全局引入axios.js文件(当然你也可以局部引用),这样就不用在组件中去调用了,因为我在axios中只有一个默认的函数抛出,所以我们不需要指定方法,直接调用该文件即可。
import request from '@/api/axios.js'
Vue.prototype.$axios = request
组件中使用
现在我们就可以开心的使用封装的axios了,直接通过this.$axios()即可调用我们axios.js文件中的输出函数,然后通过method来判断调用哪个方法即可。因为前面我们已经定义了axios.defaults.baseURL,所以这里我们只要附上路由即可,axios会自动为我们拼接路由的。
this.$axios('post','login/',{
username:this.uname,
password:this.password,
})
.then(res=>{
console.log(res)
if(res.data===200){
this.$store.commit('setToken',res.data.token)
this.$Message({
message:'登录成功',
type:'success'
})
this.$router.push('/home/info')
}
})
.catch(err => console.log(err))