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 相关文章推荐
Flash对联广告的关闭按钮讨论
Jan 30 Javascript
实现JavaScript中继承的三种方式
Oct 16 Javascript
JavaScript之appendChild、insertBefore和insertAfter使用说明
Dec 30 Javascript
浅析jQuery(function(){})与(function(){})(jQuery)之间的区别
Jan 09 Javascript
js在指定位置增加节点函数insertBefore()用法实例
Jan 12 Javascript
JavaScript实现弹出DIV层同时页面背景渐变成半透明效果
Mar 25 Javascript
knockoutjs动态加载外部的file作为component中的template数据源的实现方法
Sep 01 Javascript
使用requirejs模块化开发多页面一个入口js的使用方式
Jun 14 Javascript
解决微信二次分享不显示摘要和图片的问题
Aug 18 Javascript
JavaScript数据结构之栈实例用法
Jan 18 Javascript
超详细的5个Shell脚本实例分享(值得收藏)
Aug 15 Javascript
Vue使用mixin分发组件的可复用功能
Sep 01 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 文件上传代码(限制jpg文件)
2010/01/05 PHP
php数组函数序列之next() - 移动数组内部指针到下一个元素的位置,并返回该元素值
2011/10/31 PHP
php使用类继承解决代码重复的问题
2015/02/11 PHP
php检查页面是否被百度收录
2015/10/28 PHP
PHP自定义函数实现格式化秒的方法
2016/09/14 PHP
jQuery 判断元素上是否绑定了事件
2009/10/28 Javascript
谷歌浏览器调试JavaScript小技巧
2014/12/29 Javascript
JS随机调用指定函数的方法
2015/07/01 Javascript
JQuery的常用选择器、过滤器、方法全面介绍
2016/05/25 Javascript
jQuery获取复选框被选中数量及判断选择值的方法详解
2016/05/25 Javascript
js友好的时间返回函数
2016/08/24 Javascript
分类解析jQuery选择器
2016/11/23 Javascript
Node.js中的require.resolve方法使用简介
2017/04/23 Javascript
详解Vue中localstorage和sessionstorage的使用
2017/12/22 Javascript
node内置调试方法总结
2018/02/22 Javascript
父组件中vuex方法更新state子组件不能及时更新并渲染的完美解决方法
2018/04/25 Javascript
JavaScript对象拷贝与赋值操作实例分析
2018/12/10 Javascript
VUE+Element环境搭建与安装的方法步骤
2019/01/24 Javascript
Servlet返回的数据js解析2种方法
2019/12/12 Javascript
浅谈Vuex的this.$store.commit和在Vue项目中引用公共方法
2020/07/24 Javascript
解决Vue-cli3没有vue.config.js文件夹及配置vue项目域名的问题
2020/12/04 Vue.js
[37:22]DOTA2上海特级锦标赛D组资格赛#2 Liquid VS VP第一局
2016/02/28 DOTA
Numpy之random函数使用学习
2019/01/29 Python
PyQt4 treewidget 选择改变颜色,并设置可编辑的方法
2019/06/17 Python
jenkins配置python脚本定时任务过程图解
2019/10/29 Python
基于python图书馆管理系统设计实例详解
2020/08/05 Python
基于CSS3的animation属性实现微信拍一拍动画效果
2020/06/22 HTML / CSS
html5使用canvas绘制一张图片
2014/12/15 HTML / CSS
html5利用canvas实现颜色容差抠图功能
2019/12/23 HTML / CSS
时装界的“朋克之母”:Vivienne Westwood
2017/07/06 全球购物
有趣的流行文化T恤、马克杯、手机壳和更多:Look Human
2019/01/07 全球购物
全球精选男装和家居用品:Article
2020/04/13 全球购物
法定代表人身份证明书
2014/09/10 职场文书
2014年乡镇党建工作总结
2014/11/11 职场文书
胡桃夹子观后感
2015/06/11 职场文书
HTML5+CSS+JavaScript实现捉虫小游戏设计和实现
2021/10/16 HTML / CSS