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 相关文章推荐
javascript 出生日期和身份证判断大全
Nov 13 Javascript
MC Dialog js弹出层 完美兼容多浏览器(5.6更新)
May 06 Javascript
javascript修改图片src的方法
Jan 27 Javascript
javascript常用函数(1)
Nov 04 Javascript
JavaScript继承学习笔记【新手必看】
May 10 Javascript
node.js cookie-parser 中间件介绍
Jun 06 Javascript
vue2.0嵌套路由实现豆瓣电影分页功能(附demo)
Mar 13 Javascript
基于vue的fullpage.js单页滚动插件
Mar 20 Javascript
vue resource post请求时遇到的坑
Oct 19 Javascript
vue的状态管理模式vuex
Nov 30 Javascript
解决angularjs前后端分离调用接口传递中文时中文乱码的问题
Aug 13 Javascript
使用typescript快速开发一个cli的实现示例
Dec 09 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
mysql_fetch_assoc和mysql_fetch_row的功能加起来就是mysql_fetch_array
2007/01/15 PHP
php include,include_once,require,require_once
2008/09/05 PHP
关于PHP中Object对象的笔记分享
2011/06/28 PHP
Php图像处理类代码分享
2012/01/19 PHP
ThinkPHP 连接Oracle数据库的详细教程[全]
2012/07/16 PHP
php生成txt文件实例代码介绍
2016/04/28 PHP
基于jquery实现的鼠标拖拽元素复制并写入效果
2011/08/23 Javascript
jquery.Jwin.js 基于jquery的弹出层插件代码
2012/05/23 Javascript
jquery DIV撑大让滚动条滚到最底部代码
2013/06/06 Javascript
Extjs4 Treegrid 使用心得分享(经验篇)
2013/07/01 Javascript
js 时间函数应用加、减、比较、格式转换的示例代码
2013/08/23 Javascript
sencha touch 模仿tabpanel导航栏TabBar的实例代码
2013/10/24 Javascript
javascript通过className来获取元素的简单示例代码
2014/01/10 Javascript
jQuery 获取、设置HTML或TEXT内容的两种方法
2014/05/23 Javascript
JavaScript中点击事件的写法
2016/06/28 Javascript
用AngularJS来实现监察表单按钮的禁用效果
2016/11/02 Javascript
使用jQuery卸载全部事件的思路详解
2017/04/03 jQuery
vue页面跳转后返回原页面初始位置方法
2018/02/11 Javascript
vue2.0 element-ui中el-select选择器无法显示选中的内容(解决方法)
2018/08/24 Javascript
Javascript中绑定click事件的四种方式介绍
2018/10/26 Javascript
D3.js(v3)+react 实现带坐标与比例尺的柱形图 (V3版本)
2019/05/09 Javascript
弱类型语言javascript开发中的一些坑实例小结【变量、函数、数组、对象、作用域等】
2019/08/07 Javascript
在layui下对元素进行事件绑定的实例
2019/09/06 Javascript
Vue图片浏览组件v-viewer用法分析【支持旋转、缩放、翻转等操作】
2019/11/04 Javascript
实例讲解python函数式编程
2014/06/09 Python
浅谈Python中copy()方法的使用
2015/05/21 Python
Python模块、包(Package)概念与用法分析
2019/05/31 Python
Python hexstring-list-str之间的转换方法
2019/06/12 Python
python networkx 包绘制复杂网络关系图的实现
2019/07/10 Python
在flask中使用python-dotenv+flask-cli自定义命令(推荐)
2020/01/05 Python
Python urllib request模块发送请求实现过程解析
2020/12/10 Python
CSS3中:nth-child和:nth-of-type的区别深入理解
2014/03/10 HTML / CSS
应届毕业生自我鉴定范文
2013/12/27 职场文书
《问银河》教学反思
2014/02/19 职场文书
安全协议书范本
2014/04/21 职场文书
Python人工智能之混合高斯模型运动目标检测详解分析
2021/11/07 Python