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实现的tab效果可以指定默认显示第几页
Oct 16 Javascript
JS将光标聚焦在文本最后的实现代码
Mar 28 Javascript
JQuery 给元素绑定click事件多次执行的解决方法
Sep 09 Javascript
深入理解JavaScript系列(41):设计模式之模板方法详解
Mar 04 Javascript
JavaScript操作HTML元素和样式的方法详解
Oct 21 Javascript
layui文件上传实现代码
May 20 Javascript
React-Native 组件之 Modal的使用详解
Aug 08 Javascript
基于vue 添加axios组件,解决post传参数为null的问题
Mar 05 Javascript
JavaScript实现异步图像上传功能
Jul 12 Javascript
AngularJS修改model值时,显示内容不变的实例
Sep 13 Javascript
vue element upload实现图片本地预览
Aug 20 Javascript
解决vue单页面多个组件嵌套监听浏览器窗口变化问题
Jul 30 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
PHP中使用Session配合Javascript实现文件上传进度条功能
2014/10/15 PHP
php创建和删除目录函数介绍和递归删除目录函数分享
2014/11/18 PHP
PHP中大于2038年时间戳的问题处理方案
2015/03/03 PHP
PHP SESSION的增加、删除、修改、查看操作
2015/03/20 PHP
大家都应该掌握的PHP关联数组使用技巧
2015/12/25 PHP
PHP浮点数的一个常见问题
2016/03/10 PHP
浅析PHP中的i++与++i的区别及效率
2016/06/15 PHP
Laravel 中使用 Vue.js 实现基于 Ajax 的表单提交错误验证操作
2017/06/30 PHP
php 数据结构之链表队列
2017/10/17 PHP
使用JavaScript库还是自己写代码?
2010/01/28 Javascript
用apply让javascript函数仅执行一次的代码
2010/06/27 Javascript
使用jquery写个更改表格行顺序的小功能
2014/04/29 Javascript
简介AngularJS的视图功能应用
2015/06/17 Javascript
浅谈node.js中async异步编程
2015/10/22 Javascript
z-blog SyntaxHighlighter 长代码无法换行解决办法(基于jquery)
2015/11/18 Javascript
关于axios不能使用Vue.use()浅析
2018/01/12 Javascript
完美解决axios跨域请求出错的问题
2018/02/05 Javascript
Vue实现商品详情页的评价列表功能
2019/09/04 Javascript
微信小程序 导入图标实现过程详解
2019/10/11 Javascript
Vue解决移动端弹窗滚动穿透问题
2020/12/15 Vue.js
约瑟夫问题的Python和C++求解方法
2015/08/20 Python
举例讲解Python设计模式编程的代理模式与抽象工厂模式
2016/01/16 Python
git使用.gitignore设置不生效或不起作用问题的解决方法
2017/06/01 Python
python类的方法属性与方法属性的动态绑定代码详解
2017/12/27 Python
python使用thrift教程的方法示例
2019/03/21 Python
wxpython多线程防假死与线程间传递消息实例详解
2019/12/13 Python
python中count函数简单用法
2020/01/05 Python
HTML5 HTMLCollection和NodeList的区别详解
2020/04/29 HTML / CSS
全球最大的服务市场:Fiverr
2017/01/03 全球购物
Europcar德国:全球汽车租赁领域的领导者
2018/08/15 全球购物
TCP/IP的分层模型
2013/10/27 面试题
美术毕业生求职信
2014/02/25 职场文书
平安建设实施方案
2014/03/19 职场文书
终止劳动合同协议书
2014/04/14 职场文书
大一新生军训新闻稿
2015/07/17 职场文书
Beekeeper Studio开源数据库管理工具比Navicat更炫酷
2022/06/21 数据库