2021SC@SDUSC
一、引言
本篇博客将对老年健康知识图谱系统中发送请求及处理不同角色用户登录的源码进行分析,了解axios、token的使用以及路由守卫等内容。
二、代码分析
1.axios
在系统的登录等模块使用到了axios来发送请求。Axios,可以理解为ajax i/o system,这不是一种新技术,本质上还是对原生XMLHttpRequest的封装,可用于浏览器和nodejs的HTTP客户端,只不过它是基于Promise的,符合最新的ES规范。
axios.interceptors.request.use(config=> {
return config;
}, err=> {
Message.error({message: '请求超时!'});
return Promise.resolve(err);
})
axios.interceptors.response.use(data=> {
if (data.status && data.status == 200 && data.data.status == 'error') {
Message.error({message: data.data.msg});
return;
}
return data;
}, err=> {
if (err.response.status == 504||err.response.status == 404) {
Message.error({message: ''});
} else if (err.response.status == 403) {
Message.error({message: '权限不足,请联系管理员!'});
}else {
Message.error({message: '未知错误!'});
}
return Promise.resolve(err);
})
let base = '';
export const postRequest = (url, params) => {
return axios({
method: 'post',
url: `${base}${url}`,
data: params,
transformRequest: [function (data) {
let ret = ''
for (let it in data) {
ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
}
return ret
}],
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + window.localStorage.getItem('token') == null ? "": window.localStorage.getItem('token')
}
});
}
export const uploadFileRequest = (url, params) => {
return axios({
method: 'post',
url: `${base}${url}`,
data: params,
headers: {
'Content-Type': 'multipart/form-data'
}
});
}
export const putRequest = (url, params) => {
return axios({
method: 'put',
url: `${base}${url}`,
data: params,
transformRequest: [function (data) {
let ret = ''
for (let it in data) {
ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
}
return ret
}],
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
}
export const deleteRequest = (url) => {
return axios({
method: 'delete',
url: `${base}${url}`
});
}
export const getRequest = (url) => {
return axios({
method: 'get',
url: `${base}${url}`,
headers: {
'Authorization': window.localStorage.getItem('token') == null ? "": 'Bearer '+ window.localStorage.getItem('token')
}
});
}
这其中用到了拦截器interceptors。拦截器是指当发送请求或者得到响应被then或catch处理之前对它们进行拦截,拦截后可对数据做一些处理,比如给请求数据添加头部信息,或对响应数据进行序列化,然后再传给浏览器,这些都可以在拦截器中进行。
2.token的使用以及路由守卫
接下来会对项目中使用到的token相关内容进行分析。首先对token的概念和使用token的原因进行大致的说明:
Token的定义:Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
Token的引入:Token是在客户端频繁向服务端请求数据,服务端频繁的去数据库查询用户名和密码并进行对比,判断用户名和密码正确与否,并作出相应提示,在这样的背景下,Token便应运而生。
使用Token的目的:Token的目的是为了减轻服务器的压力,减少频繁的查询数据库,使服务器更加健壮。
在本系统中,,登录页面时,我们向后端传递了用户名及密码,此时如果在数据库中有对应,那么后端就会返回给我们一个token值。获取token后,我们首先使用如下代码:
window.sessionStorage.setItem("token", successResponse.data.token)
将获取到的token值储存在本地中。sessionStorage.setItem()方法将数据以键值对的形式暂时储存在本地中,用于临时保存同一窗口或者标签页的数据。
设置路由守卫,url会被默认跳转成/login:
router.beforeEach((to, from, next) => {
if(to.path === '/login' || to.path === '/register') return next();
to 将要访问的路径,from 代表从哪个路径跳转而来,next 是一个函数,表示放行,next() 放行, next(’/login’) 强制跳转。 设置’/login’和’/register’不被拦截。
获取token:
const tokenStr = window.sessionStorage.getItem('token');
if(!tokenStr) return next('/login')
next()
})
该路由守卫设置‘/login’ 和 '/register’不被拦截,当要直接访问其他的页面时,判断是否有token,若有,则不拦截,反之,则将页面自动跳转到/login。