详解给Vue2路由导航钩子和axios拦截器做个封装


Posted in Javascript onApril 10, 2018

1.写在前面

最近在学习Vue2,遇到有些页面请求数据需要用户登录权限、服务器响应不符预期的问题,但是总不能每个页面都做单独处理吧,于是想到axios提供了拦截器这个好东西,再于是就出现了本文。

2.具体需求

  1. 用户鉴权与重定向:使用Vue提供的路由导航钩子
  2. 请求数据序列化:使用axios提供的请求拦截器
  3. 接口报错信息处理:使用axios提供的响应拦截器

3.简单实现

3.1 路由导航钩子层面鉴权与重定向的封装

路由导航钩子所有配置均在router/index.js,这里是部分代码

import Vue from 'vue'
import Router from 'vue-router'
import { getUserData } from '@/script/localUserData'

const MyAddress = r => require.ensure([], () => r(require('@/views/MyAddress/MyAddress')), 'MyAddress')

Vue.use(Router)

const routes = [
 {
  path: '/profile/address',
  name: 'MyAddress',
  component: MyAddress,
  meta: {
   title: '我的地址',
   requireAuth: true
  }
 },
 // 更多...
]

const router = new Router({
 mode: 'history',
 routes
})

我们主要来看下面逻辑处理部分的代码

let indexScrollTop = 0
router.beforeEach((to, from, next) => {
 // 路由进入下一个路由对象前,判断是否需要登陆
 // 在路由meta对象中由个requireAuth字段,只要此字段为true,必须做鉴权处理
 if (to.matched.some(res => res.meta.requireAuth)) {
  // userData为存储在本地的一些用户信息
  let userData = getUserData()
  // 未登录和已经登录的处理
  // getUserData方法处理后如果userData.token没有值就是undefined,下面直接判断
  if (userData.token === undefined) {
   // 执行到此处说明没有登录,君可按需处理之后再执行如下方法去登录页面
   // 我这里没有其他处理,直接去了登录页面
   next({
    path: '/login',
    query: {
     redirect: to.path
    }
   })
  } else {
   // 执行到说明本地存储有用户信息
   // 但是用户信息是否过期还是需要验证一下滴
   let overdueTime = userData.overdueTime
   let nowTime = +new Date
   // 登陆过期和未过期
   if (nowTime > overdueTime) {
    // 登录过期的处理,君可按需处理之后再执行如下方法去登录页面
    // 我这里没有其他处理,直接去了登录页面
    next({
     path: '/login',
     query: {
      redirect: to.path
     }
    })
   } else {
    next()
   }
  }
 } else {
  next()
 }
 if (to.path !== '/') {
  indexScrollTop = document.body.scrollTop
 }
 document.title = to.meta.title || document.title
})

router.afterEach(route => {
 if (route.path !== '/') {
  document.body.scrollTop = 0
 } else {
  Vue.nextTick(() => {
   document.body.scrollTop = indexScrollTop
  })
 }
})
export default router

至此,路由钩子层面的鉴权处理完毕,不过细心的你可能注意到:导航去登录页面调用的next方法里面有个query对象,携带了目标路由的地址,这是因为在登录成功后我们需要重定向到目标页面。

3.2 对axios拦截器封装

axios所有配置均在件script/getData.js文件,这里是本文件公共代码部分

```

import qs from 'qs'

import { getUserData } from '@/script/localUserData '

import router from '@/router '

import axios from 'axios'

import { AJAX_URL } from '@/config/index '

axios.defaults.baseURL = AJAX_URL

> axios请求拦截器代码

 ```
/**
 * 请求拦截器,请求发送之前做些事情
 */
axios.interceptors.request.use(
 config => {
  // POST || PUT || DELETE请求时先格式化data数据
  // 这里需要引入第三方模块qs
  if (
   config.method.toLocaleUpperCase() === 'POST' ||
   config.method.toLocaleUpperCase() === 'PUT' ||
   config.method.toLocaleUpperCase() === 'DELETE'
  ) {
   config.data = qs.stringify(config.data)
  }
  // 配置Authorization参数携带用户token
  let userData = getUserData()
  if (userData.token) {
   config.headers.Authorization = userData.token
  }
  return config
 },
 error => {
  // 此处应为弹窗显示具体错误信息,因为是练手项目,劣者省略此处
  // 君可自行写 || 引入第三方UI框架
  console.error(error)
  return Promise.reject(error)
 }
)

axios响应拦截器代码

/**
 * 响应拦截器,请求返回异常统一处理
 */
axios.interceptors.response.use(
 response => {
  // 这段代码很多场景下没用
  if (response.data && response.data.success === false) {
   // 根据实际情况的一些处理逻辑...
   return Promise.reject(response)
  }
  return response
 },
 error => {
  // 此处报错可能因素比较多
  // 1.需要授权处用户还未登录,因为路由段有验证是否登陆,此处理论上不会出现
  // 2.需要授权处用户登登录过期
  // 3.请求错误 4xx
  // 5.服务器错误 5xx
  // 关于鉴权失败,与后端约定状态码为500
  switch (error.response.status) {
   case 403:
    // 一些处理...
    break
   case 404:
    // 一些处理...
    break
   case 500:
    let userData = getUserData()
    if (userData.token === undefined) {
     // 此处为未登录处理
     // 一些处理之后...再去登录页面...
     // router.push({
     //  path: '/login'
     // })
    } else {
     let overdueTime = userData.overdueTime
     let nowTime = +new Date
     if (overdueTime && nowTime > overdueTime) {
      // 此处登录过期的处理
      // 一些处理之后...再去登录页面...
      // router.push({
      //  path: '/login'
      // })
     } else {
      // 极端情况,登录未过期,但是不知道哪儿错了
      // 按需处理吧...我暴力回到了首页
      router.push({
       path: '/'
      })
     }
    }
    break
   case 501:
    // 一些处理...
    break
   default:
    // 状态码辣么多,按需配置...
    break
  }
  return Promise.reject(error)
 }
)

想了解更多关于axios的信息?请移步 这里 。

这个封装很简单,面对复杂的业务肯定还需要更多的考量,但是对于一般的小项目或边缘业务也差不多够用了。最后希望这篇文章能对有需要的同学提供一些帮助。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
响应鼠标变换表格背景或者颜色的代码
Mar 30 Javascript
Javascript this指针
Jul 30 Javascript
jQuery 源码分析笔记(3) Deferred机制
Jun 19 Javascript
关于js日期转化为毫秒数“节省20%的效率和和节省9个字符“问题
Mar 01 Javascript
JS控制图片等比例缩放的示例代码
Dec 24 Javascript
js实现网页抽奖实例
Aug 05 Javascript
Bootstrap学习笔记之css样式设计(2)
Jun 07 Javascript
微信小程序 Buffer缓冲区的详解
Jul 06 Javascript
详解使用nvm安装node.js
Jul 18 Javascript
微信h5静默和非静默授权获取用户openId的方法和步骤
Jun 08 Javascript
vue $mount 和 el的区别说明
Sep 11 Javascript
吃通javascript正则表达式
Apr 21 Javascript
详解webpack 打包文件体积过大解决方案(code splitting)
Apr 10 #Javascript
Angular CLI在Angular项目中如何使用scss详解
Apr 10 #Javascript
vue2.0+koa2+mongodb实现注册登录
Apr 10 #Javascript
bing Map 在vue项目中的使用详解
Apr 09 #Javascript
详解Vue打包优化之code spliting
Apr 09 #Javascript
node实现基于token的身份验证
Apr 09 #Javascript
vue-cli扩展多模块打包的示例代码
Apr 09 #Javascript
You might like
php is_file()和is_dir()用于遍历目录时用法注意事项
2010/03/02 PHP
PHP中比较时间大小实例
2014/08/21 PHP
PHP编写登录验证码功能 附调用方法
2016/05/19 PHP
JS动画效果代码3
2008/04/03 Javascript
番茄的表单验证类代码修改版
2008/07/18 Javascript
web 页面分页打印的实现
2009/06/22 Javascript
javascript中将Object转换为String函数代码 (json str)
2012/04/29 Javascript
js处理json以及字符串的比较等常用操作
2013/09/08 Javascript
jquery通过a标签删除table中的一行的代码
2013/12/02 Javascript
JavaScript中localStorage对象存储方式实例分析
2017/01/12 Javascript
基于hover的用法实例(推荐)
2017/07/04 Javascript
使用MUI框架模拟手机端的下拉刷新和上拉加载功能
2017/09/04 Javascript
angularjs结合html5实现拖拽功能
2018/06/25 Javascript
jquery css实现流程进度条
2020/03/26 jQuery
javascript实现打砖块小游戏(附完整源码)
2020/09/18 Javascript
Python(Tornado)模拟登录小米抢手机
2013/11/12 Python
Python实现求解括号匹配问题的方法
2018/04/17 Python
python实现一个简单的ping工具方法
2019/01/31 Python
Python常用的json标准库
2019/02/19 Python
Python实现九宫格式的朋友圈功能内附“马云”朋友圈
2019/05/07 Python
python递归下载文件夹下所有文件
2019/08/31 Python
Python Sphinx使用实例及问题解决
2020/01/17 Python
浅谈在django中使用redirect重定向数据传输的问题
2020/03/13 Python
Python使用Chrome插件实现爬虫过程图解
2020/06/09 Python
Python环境管理virtualenv&virtualenvwrapper的配置详解
2020/07/01 Python
keras分类之二分类实例(Cat and dog)
2020/07/09 Python
Python Selenium实现无可视化界面过程解析
2020/08/25 Python
HTML5进度条特效
2014/12/18 HTML / CSS
社区党员先进事迹
2014/01/22 职场文书
2014流动人口计划生育工作总结
2014/12/20 职场文书
毕业答辩开场白范文
2015/05/27 职场文书
升职自荐书
2019/05/09 职场文书
如何利用 CSS Overview 面板重构优化你的网站
2021/10/24 HTML / CSS
浅谈克隆 JavaScript
2021/11/02 Javascript
中国十大神话动漫电影排行榜 哪吒登顶 白蛇缘起排第七
2022/03/21 国漫
idea下配置tomcat避坑详解
2022/04/12 Servers