Vue中axios的封装(报错、鉴权、跳转、拦截、提示)


Posted in Javascript onAugust 20, 2019
  • 统一捕获接口报错
  • 弹窗提示
  • 报错重定向
  • 基础鉴权
  • 表单序列化

实现的功能

  • 统一捕获接口报错 : 用的axios内置的拦截器
  • 弹窗提示: 引入 Element UI 的 Message 组件
  • 报错重定向: 路由钩子
  • 基础鉴权: 服务端过期时间戳和token,还有借助路由的钩子
  • 表单序列化: 我这边直接用 qs (npm模块),你有时间也可以自己写

用法及封装

用法

// 服务层 , import默认会找该目录下index.js的文件,这个可能有小伙伴不知道
// 可以去了解npm的引入和es6引入的理论概念
import axiosPlugin from "./server"; 
Vue.use(axiosPlugin);

对axios的封装(AXIOS: index.js )

import axios from "axios";
import qs from "qs";
import { Message } from "element-ui";
import router from "../router";
const Axios = axios.create({
 baseURL: "/", // 因为我本地做了反向代理
 timeout: 10000,
 responseType: "json",
 withCredentials: true, // 是否允许带cookie这些
 headers: {
  "Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
 }
});
//POST传参序列化(添加请求拦截器)
Axios.interceptors.request.use(
 config => {
  // 在发送请求之前做某件事
  if (
   config.method === "post"
  ) {
   // 序列化
   config.data = qs.stringify(config.data);
   // 温馨提示,若是贵公司的提交能直接接受json 格式,可以不用 qs 来序列化的
  }
  // 若是有做鉴权token , 就给头部带上token
  // 若是需要跨站点,存放到 cookie 会好一点,限制也没那么多,有些浏览环境限制了 localstorage 的使用
  // 这里localStorage一般是请求成功后我们自行写入到本地的,因为你放在vuex刷新就没了
  // 一些必要的数据写入本地,优先从本地读取
  if (localStorage.token) {
   config.headers.Authorization = localStorage.token;
  }
  return config;
 },
 error => {
  // error 的回调信息,看贵公司的定义
  Message({
   // 饿了么的消息弹窗组件,类似toast
   showClose: true,
   message: error && error.data.error.message,
   type: 'error'
  });
  return Promise.reject(error.data.error.message);
 }
);
//返回状态判断(添加响应拦截器)
Axios.interceptors.response.use(
 res => {
  //对响应数据做些事
  if (res.data && !res.data.success) {
   Message({
    // 饿了么的消息弹窗组件,类似toast
    showClose: true,
    message: res.data.error.message.message
     ? res.data.error.message.message
     : res.data.error.message,
    type: "error"
   });
   return Promise.reject(res.data.error.message);
  }
  return res;
 },
 error => {
  // 用户登录的时候会拿到一个基础信息,比如用户名,token,过期时间戳
  // 直接丢localStorage或者sessionStorage
  if (!window.localStorage.getItem("loginUserBaseInfo")) {
   // 若是接口访问的时候没有发现有鉴权的基础信息,直接返回登录页
   router.push({
    path: "/login"
   });
  } else {
   // 若是有基础信息的情况下,判断时间戳和当前的时间,若是当前的时间大于服务器过期的时间
   // 乖乖的返回去登录页重新登录
   let lifeTime =
    JSON.parse(window.localStorage.getItem("loginUserBaseInfo")).lifeTime *
    1000;
   let nowTime = new Date().getTime(); // 当前时间的时间戳
   console.log(nowTime, lifeTime);
   console.log(nowTime > lifeTime);
   if (nowTime > lifeTime) {
    Message({
     showClose: true,
     message: "登录状态信息过期,请重新登录",
     type: "error"
    });
    router.push({
     path: "/login"
    });
   } else {
    // 下面是接口回调的satus ,因为我做了一些错误页面,所以都会指向对应的报错页面
    if (error.response.status === 403) {
     router.push({
      path: "/error/403"
     });
    }
    if (error.response.status === 500) {
     router.push({
      path: "/error/500"
     });
    }
    if (error.response.status === 502) {
     router.push({
      path: "/error/502"
     });
    }
    if (error.response.status === 404) {
     router.push({
      path: "/error/404"
     });
    }
   }
  }
  // 返回 response 里的错误信息
  let errorInfo = error.data.error ? error.data.error.message : error.data;
  return Promise.reject(errorInfo);
 }
);
// 对axios的实例重新封装成一个plugin ,方便 Vue.use(xxxx)
export default {
 install: function(Vue, Option) {
  Object.defineProperty(Vue.prototype, "$http", { value: Axios });
 }
};

路由钩子的调整(Router: index.js )

import Vue from "vue";
import Router from "vue-router";
import layout from "@/components/layout/layout";
// 版块有点多,版块独立路由管理,里面都是懒加载引入
import customerManage from "./customerManage"; // 客户管理
import account from "./account"; //登录
import adManage from "./adManage"; // 广告管理
import dataStat from "./dataStat"; // 数据统计
import logger from "./logger"; // 日志
import manager from "./manager"; // 管理者
import putonManage from "./putonManage"; // 投放管理
import error from "./error"; // 服务端错误
import { Message } from "element-ui";
Vue.use(Router);
// 请跳过这一段,看下面的
const router = new Router({
 hashbang: false,
 mode: "history",
 routes: [
  {
   path: "/",
   redirect: "/adver",
   component: layout,
   children: [
    ...customerManage,
    ...adManage,
    ...dataStat,
    ...putonManage,
    ...manager,
    ...logger
   ]
  },
  ...account,
  ...error
 ]
});
// 路由拦截
// 差点忘了说明,不是所有版块都需要鉴权的
// 所以需要鉴权,我都会在路由meta添加添加一个字段requireLogin,设置为true的时候
// 这货就必须走鉴权,像登录页这些不要,是可以直接访问的!!!
router.beforeEach((to, from, next) => {
 if (to.matched.some(res => res.meta.requireLogin)) {
  // 判断是否需要登录权限
  if (window.localStorage.getItem("loginUserBaseInfo")) {
   // 判断是否登录
   let lifeTime =
    JSON.parse(window.localStorage.getItem("loginUserBaseInfo")).lifeTime *
    1000;
   let nowTime = (new Date()).getTime(); // 当前时间的时间戳
   if (nowTime < lifeTime) {
    next();
   } else {
    Message({
     showClose: true,
     message: "登录状态信息过期,请重新登录",
     type: "error"
    });
    next({
     path: "/login"
    });
   }
  } else {
   // 没登录则跳转到登录界面
   next({
    path: "/login"
   });
  }
 } else {
  next();
 }
});
export default router;

axios可配置的一些选项,其他的具体看官网说明哈

export default {
 // 请求地址
 url: "/user",
 // 请求类型
 method: "get",
 // 请根路径
 baseURL: "http://www.mt.com/api",
 // 请求前的数据处理
 transformRequest: [function(data) {}],
 // 请求后的数据处理
 transformResponse: [function(data) {}],
 // 自定义的请求头
 headers: { "x-Requested-With": "XMLHttpRequest" },
 // URL查询对象
 params: { id: 12 },
 // 查询对象序列化函数
 paramsSerializer: function(params) {},
 // request body
 data: { key: "aa" },
 // 超时设置s
 timeout: 1000,
 // 跨域是否带Token
 withCredentials: false,
 // 自定义请求处理
 adapter: function(resolve, reject, config) {},
 // 身份验证信息
 auth: { uname: "", pwd: "12" },
 // 响应的数据格式 json / blob /document /arraybuffer / text / stream
 responseType: "json",
 // xsrf 设置
 xsrfCookieName: "XSRF-TOKEN",
 xsrfHeaderName: "X-XSRF-TOKEN",

 // 下传和下载进度回调
 onUploadProgress: function(progressEvent) {
  Math.round(progressEvent.loaded * 100 / progressEvent.total);
 },
 onDownloadProgress: function(progressEvent) {},

 // 最多转发数,用于node.js
 maxRedirects: 5,
 // 最大响应数据大小
 maxContentLength: 2000,
 // 自定义错误状态码范围
 validateStatus: function(status) {
  return status >= 200 && status < 300;
 },
 // 用于node.js
 httpAgent: new http.Agent({ keepAlive: true }),
 httpsAgent: new https.Agent({ keepAlive: true }),

 // 用于设置跨域请求代理
 proxy: {
  host: "127.0.0.1",
  port: 8080,
  auth: {
   username: "aa",
   password: "2123"
  }
 },
 // 用于取消请求
 cancelToken: new CancelToken(function(cancel) {})
};

总结

这个封装虽说不是万金油版本,但是我感觉大多用axios结合vue的小伙伴,稍微改改都能直接拿来用

鉴权需要再严谨一些,比如token 可以遵循 JWT 的规格,以及引入中间层nodejs(对传输的做拦截封装加解密,聚合接口);

以上所述是小编给大家介绍的Vue中axios的封装(报错、鉴权、跳转、拦截、提示),希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Javascript 相关文章推荐
关于jquery性能最佳实践的讨论,与求教
Mar 30 Javascript
js+JQuery返回顶部功能如何实现
Dec 03 Javascript
基于JQuery实现滚动到页面底端时自动加载更多信息
Jan 31 Javascript
一个可以增加和删除行的table并可编辑表格中内容
Jun 16 Javascript
js仿黑客帝国字母掉落效果代码分享
Nov 08 Javascript
jQuery ajax 当async为false时解决同步操作失败的问题
Nov 18 Javascript
深入理解Vue.js源码之事件机制
Sep 27 Javascript
vue.js项目中实用的小技巧汇总
Nov 29 Javascript
浅谈开发eslint规则
Oct 01 Javascript
layui实现二维码弹窗、并下载到本地的方法
Sep 25 Javascript
Vue中点击active并第一个默认选中功能的实现
Feb 24 Javascript
vue实现移动端input上传视频、音频
Aug 18 Javascript
Vue formData实现图片上传
Aug 20 #Javascript
Angular8 Http拦截器简单使用教程
Aug 20 #Javascript
vue实现axios图片上传功能
Aug 20 #Javascript
扫微信小程序码实现网站登陆实现解析
Aug 20 #Javascript
vue+element-ui+axios实现图片上传
Aug 20 #Javascript
vue element upload实现图片本地预览
Aug 20 #Javascript
JS中的算法与数据结构之集合(Set)实例详解
Aug 20 #Javascript
You might like
不用mod_rewrite直接用php实现伪静态化页面代码
2008/10/04 PHP
PHP下通过QRCode类库创建中间带网站LOGO的二维码
2014/07/12 PHP
php实现简易聊天室应用代码
2015/09/23 PHP
JavaScript关于select的相关操作说明
2010/01/13 Javascript
基于jQuery的js分页代码
2010/06/10 Javascript
javascript预览上传图片发现的问题的解决方法
2010/11/25 Javascript
window.addEventListener来解决让一个js事件执行多个函数
2012/12/26 Javascript
Yii-自定义删除确认弹框(zyd)jquery实现代码
2013/03/04 Javascript
jquery 取子节点及当前节点属性值
2014/07/25 Javascript
JS的location.href跳出框架打开新页面的方法
2014/09/04 Javascript
JS获得选取checkbox整行数据的方法
2015/01/28 Javascript
javascript关于运动的各种问题经典总结
2015/04/27 Javascript
基于jQuery+PHP+Mysql实现在线拍照和在线浏览照片
2015/09/06 Javascript
Bootstrap每天必学之日期控制
2016/03/07 Javascript
基于jQuery下拉选择框插件支持单选多选功能代码
2016/06/07 Javascript
用headjs来管理和加载js 提高网站加载速度
2016/11/29 Javascript
JS编写函数实现对身份证号码最后一位的验证功能
2016/12/29 Javascript
jQuery制作图片旋转效果
2017/02/02 Javascript
Bootstrap模态框插入视频的实现代码
2017/06/25 Javascript
vue+vux实现移动端文件上传样式
2017/07/28 Javascript
angularjs实现天气预报功能
2020/06/16 Javascript
JavaScript笛卡尔积超简单实现算法示例
2018/07/30 Javascript
微信小程序模板template简单用法示例
2018/12/04 Javascript
5分钟教你用nodeJS手写一个mock数据服务器的方法
2019/09/10 NodeJs
python 实现自动远程登陆scp文件实例代码
2017/03/13 Python
python数据类型_元组、字典常用操作方法(介绍)
2017/05/30 Python
Python中optparser库用法实例详解
2018/01/26 Python
使用 Python 实现简单的 switch/case 语句的方法
2018/09/17 Python
基于python实现学生信息管理系统
2019/11/22 Python
编程输出如下图形
2013/11/24 面试题
机关办公室岗位职责
2014/04/16 职场文书
图书馆标语
2014/06/19 职场文书
班主任与学生安全责任书
2014/07/25 职场文书
考试作弊检讨书怎么写?
2014/12/21 职场文书
工作证明书
2015/06/15 职场文书
护理工作心得体会
2016/01/22 职场文书