##、vue-resource请求数据的时候不能携带参数的问题
this.$http.get的data部分,必需写成{params {key: value}}
的形式,否则不能携带参数传递。
##、vue-resource拦截器使用
在vue项目使用vue-resource的过程中,临时增加了一个需求,需要在任何一个页面任何一次http请求,增加对token过期的判断,如果token已过期,需要跳转至登录页面。如果要在每个页面中的http请求操作中添加一次判断,那么会是一个非常大的修改工作量。
vue-resource的interceptors拦截器的作用正是解决此需求的妙方。在每次http的请求响应之后,如果设置了拦截器如下,会优先执行拦截器函数,获取响应体,然后才会决定是否把response返回给then进行接收。那么我们可以在这个拦截器里边添加对响应状态码的判断,来决定是跳转到登录页面还是留在当前页面继续获取数据。
一、vue-resource
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
//首先在定义路由的时候就需要多添加一个自定义字段requireAuth,用于判断该路由的访问是否需要登录。如果用户已经登录,则顺利进入路由, 否则就进入登录页面。
const routes = [{
path: '/',
name: '/',
component: Index
},
{
path: '/repository',
name: 'repository',
meta: {
requireAuth: true, // 添加该字段,表示进入这个路由是需要登录的
},
component: Repository
},
{
path: '/login',
name: 'login',
component: Login
}
];
//定义完路由后,我们主要是利用vue-router提供的钩子函数beforeEach()对路由进行判断。
// 判断是否需要登录权限 以及是否登录
router.beforeEach((to, from, next) => {
if(to.meta.requireAuth) { // 判断是否需要登录权限
if(localStorage.getItem('username')) { // 判断是否登录
next()
} else { // 没登录则跳转到登录界面
next({
path: '/login',
query: {
redirect: to.fullPath
}
})
}
} else {
next()
}
})
export default router
//钩子方法接收三个参数:
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next(’/’) 或者 next({ path: ‘/’ }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
确保要调用 next 方法,否则钩子就不会被 resolved。
二、拦截器
/*http配置*/
// 引入axios以及element ui中的loading和message组件
import axios from 'axios'
import { Loading, Message } from 'element-ui'
// 超时时间
axios.defaults.timeout = 5000
// http request请求拦截器
var loadinginstace;
axios.interceptors.request.use(config => {
// element ui Loading方法
loadinginstace = Loading.service({
fullscreen: true
})
return config
}, error => {
loadinginstace.close()
Message.error({
message: '加载超时'
})
return Promise.reject(error)
})
// http response 响应拦截器
axios.interceptors.response.use(data => { // 响应成功关闭loading
loadinginstace.close()
return data
}, error => {
if(error.response) {
loadinginstace.close()
Message.error({
message: '加载失败'
});
switch(error.response.status) {
case 401:
// 返回 401 清除token信息并跳转到登录页面
localStorage.removeItem("CRM_token"); //清除token
router.replace({
path: 'login',
query: {
redirect: router.currentRoute.fullPath
}
})
}
}
return Promise.reject(error)
})
export default axios;
##、axios及axios拦截器的使用
在main.js中写入
引入axios,并将
a
x
i
o
s
设
置
爱
V
u
e
的
p
r
o
t
o
t
y
p
e
下
,
一
边
在
页
面
中
直
接
使
用
t
h
i
s
.
axios设置爱Vue的prototype下,一边在页面中直接使用this.
axios设置爱Vue的prototype下,一边在页面中直接使用this.axios.get/post就可以使用;对于$qs是对于post请求的发送数据的格式化,转成类似于get请求的发送的数据的格式,以便后台接收,具体使用方法见下图:
// 超时时间
axios.defaults.timeout = 5000
//vuejs过滤器,所有请求前调用,next返回response处理
axios.interceptors.request.use(
(config) => {
if (localStorage.zhdj_token) { // 判断是否存在token,如果存在的话,则每个http header都加上token
console.log(localStorage.zhdj_token)
config.headers.Authorization = localStorage.zhdj_token;
}else{
router.replace({ path: 'login' })
}
return config;
},err => {
return Promise.reject(err);
}
);
// http response 响应拦截器(若是未登录状态则调至登录页面)
axios.interceptors.response.use(data => {
if(data.data.code==50000){
router.replace({ path: 'login' })
}
return data;
}, error => {
return Promise.reject(error)
})
##、axios结合使用formData进行数据传输
getFile(e){
let that = this;
let files = e.target.files || e.dataTransfer.files;
let formData = new FormData();
formData.append('file', files[0]);
let config = {
headers: {
'Content-Type': 'multipart/form-data' //之前说的以表单传数据的格式来传递fromdata
}
};
that.$axios.post('/api/csv/import/deliver', formData, config).then((res) => {
console.log(res)
}).catch((error) =>{
});
},
##、解决axios 低版本浏览器不支持 finally函数的方法
安装包: promise.prototype.finally
npm i promise.prototype.finally -S
使用时引用即可:
import axios from 'axios';
require("promise.prototype.finally").shim();