书接上回,上面讲了uni-app的package.json的生成和使用以及router的使用,还讲了多环境下的环境变量的配置,这一篇说一下request卫士,router卫士,请求函数封装,安全之类的
一:request卫士--在实际开发过程中,我们可能需要对买次请求的过程进行监督,并Do something,所以就需要封装一个全局的request卫士用来监听,如下配置:在main.js中
import axios from 'axios'
// request interceptor
axios.interceptors.request.use(
config => {
// Do something before request is sent
//与yii2框架对应好token
// var token = 'tk'; //这个地方为了测试是写死的,实际情况应该是在cookie中动态获取,来判断时候有了token
// config.headers.common["Authorization"] = `Bearer ${token}`;
return config
},
error => {
// Do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
// respone interceptor
axios.interceptors.response.use(
// response => response,
/**
* 下面的注释为通过在response里,自定义code来标示请求状态
* 当code返回如下情况则说明权限有问题,登出并返回到登录页
* 如想通过xmlhttprequest来状态码标识 逻辑可写在下面error中
* 以下代码均为样例,请结合自生需求加以修改,若不需要,则可删除
*/
response => {
const res = response.data
// if (res.error_code !== 0) {
// Message({
// // message: res.error_msg,
// message: '返回数据出错',
// type: 'error',
// duration: 2 * 1000
// })
// // 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
// if (res.error_code === 10009) {
// // 请自行在引入 MessageBox
// // import { Message, MessageBox } from 'element-ui'
// MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
// confirmButtonText: '重新登录',
// cancelButtonText: '取消',
// type: 'warning'
// }).then(() => {
// store.dispatch('FedLogOut').then(() => {
// location.reload() // 为了重新实例化vue-router对象 避免bug
// })
// })
// }
// return Promise.reject(response.data)
// } else {
// return response
// }
if (response.data !== undefined && response.data.status === -1) {
//返回接口错误信息
return Promise.reject(response.data)
}
return response
},
error => {
const reg = new RegExp(/504|503|500|400/)
if (reg.test(error.message) || error.message === 'Network Error') {
Message({
message: '网络断了,请检查网络!',
type: 'error',
duration: 5 * 1000
})
} else {
Message({
// message: error.message,
message: '网络断了,请检查网络!',
type: 'error',
duration: 5 * 1000
})
}
return Promise.reject(error)
}
)
备注:这里是对axios请求进行的监控,如果你使用其他请求方式,原理是一样的,当然你也可以单独拉一个js文件把这个内容写到里面,在main.js中引入即可
二:router卫士,开发中我们不光要对request进行监控,同时还需要对每次路由跳转进行监控,这里就需要用到vue的路由卫士,可在之前创建的router文件夹下的index.js文件添加如下代码
const whiteList = ['/login','/','/adduser','/recoverpassword'] // 路由白名单
//全局路由前置守卫
router.beforeEach((to, from, next) => {
next()
// if (getToken() == 'chinacar') { // determine if there has token
// next()
// } else {
// if (whiteList.indexOf(to.path) != -1) { // 在免登录白名单,直接进入
// next()
// } else {
// next() // 否则全部重定向到登录页
// }
// }
})
// 全局路由后置守卫
router.afterEach((to, from) => {
// do som
})
这样在每次跳转的时候就可以监控一下然后做相应处理了
三:对请求函数的封装,这里讲对axios的封装,其他类似
1.在根目录下创建api文件夹,然后里面创建对应的分类接口js文件,如用于login的可以创建一个login.js文件,然后在使用的组件中import即可使用,如:login.js中可以如下书写
import axios from 'axios'
//通过账号密码登陆
export function login(params) {
let url = process.env.BASE_API + 'chinaCar/frontend/web/?r=login/login'
return axios.post(url,params)
}
在要使用的组建中如下引用
import { login } from '@/api/login' //请求函数
login(users).then(res => {
let { data } = res
if (data.code == 201) {
this.$message({
type: 'warning',
message: data.message
});
this.lgLoading = false
this.logins = '登录'
}
if (data.code == 200) {
setUserInfo(data.data)
this.lgLoading = false
this.logins = '登录'
this.$router.push({ path: '/' })
}
}).catch(err => {
this.$message({
type: 'warning',
message: '登录失败,请重新登录!'
});
this.lgLoading = false
this.logins = '登录'
})
这样就OK了。
四:安全方面的考虑
1.因为HTTP协议是开放的,可以任人调用。所以,如果接口不希望被随意调用,就需要做访问权限的控制,认证是好的用户,才允许调用API。目前主流的访问权限控制/认证模式有很多,我常用bearer token的方式既token令牌,在用户登录后,后端随机生成加密令牌(可以设置时效),传给前端,前端贮存在vuex中或cookie中,在每次request请求的时候写入header,供后端进行令牌验证,思路就是如此,下面具体看前端代码,在之前写的request卫士中,如下代码控制
axios.interceptors.request.use(
config => {
// Do something before request is sent
//与yii2框架对应好token
// var token = 'tk'; //这个地方为了测试是写死的,实际情况应该是在cookie中动态获取,来判断时候有了token
// config.headers.common["Authorization"] = `Bearer ${token}`;
return config
},
error => {
// Do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
2.不只前后端互动的时候需要安全考虑,在前端路由的时候也需要安全,这时候路由卫士就起作用了,前面写的路由卫士代码,可以在跳转之前验证一下token,如果token过期或者token不对,就进行返回登录页操作,如下
if (getToken() == 'xxxxxx') { // determine if there has token
next()
} else {
if (whiteList.indexOf(to.path) != -1) { // 在免登录白名单,直接进入
next()
} else {
next('/') // 否则全部重定向到登录页
}
}
当然这里可以做很多操作,只是简单一例,比如还可以进行退出操作,既把之前登录的时候存储的userinfo全部清除等等