经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
Vue中axios的封装(报错、鉴权、跳转、拦截、提示)
来源:jb51  时间:2019/8/21 9:16:49  对本文有异议
  • 统一捕获接口报错
  • 弹窗提示
  • 报错重定向
  • 基础鉴权
  • 表单序列化

实现的功能

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

用法及封装

用法

  1. // 服务层 , import默认会找该目录下index.js的文件,这个可能有小伙伴不知道
  2. // 可以去了解npm的引入和es6引入的理论概念
  3. import axiosPlugin from "./server";
  4. Vue.use(axiosPlugin);
  5.  
  6. axios的封装(AXIOS: index.js )
  7.  
  8. import axios from "axios";
  9. import qs from "qs";
  10. import { Message } from "element-ui";
  11. import router from "../router";
  12. const Axios = axios.create({
  13. baseURL: "/", // 因为我本地做了反向代理
  14. timeout: 10000,
  15. responseType: "json",
  16. withCredentials: true, // 是否允许带cookie这些
  17. headers: {
  18. "Content-Type": "application/x-www-form-urlencoded;charset=utf-8"
  19. }
  20. });
  21. //POST传参序列化(添加请求拦截器)
  22. Axios.interceptors.request.use(
  23. config => {
  24. // 在发送请求之前做某件事
  25. if (
  26. config.method === "post"
  27. ) {
  28. // 序列化
  29. config.data = qs.stringify(config.data);
  30. // 温馨提示,若是贵公司的提交能直接接受json 格式,可以不用 qs 来序列化的
  31. }
  32. // 若是有做鉴权token , 就给头部带上token
  33. // 若是需要跨站点,存放到 cookie 会好一点,限制也没那么多,有些浏览环境限制了 localstorage 的使用
  34. // 这里localStorage一般是请求成功后我们自行写入到本地的,因为你放在vuex刷新就没了
  35. // 一些必要的数据写入本地,优先从本地读取
  36. if (localStorage.token) {
  37. config.headers.Authorization = localStorage.token;
  38. }
  39. return config;
  40. },
  41. error => {
  42. // error 的回调信息,看贵公司的定义
  43. Message({
  44. // 饿了么的消息弹窗组件,类似toast
  45. showClose: true,
  46. message: error && error.data.error.message,
  47. type: 'error'
  48. });
  49. return Promise.reject(error.data.error.message);
  50. }
  51. );
  52. //返回状态判断(添加响应拦截器)
  53. Axios.interceptors.response.use(
  54. res => {
  55. //对响应数据做些事
  56. if (res.data && !res.data.success) {
  57. Message({
  58. // 饿了么的消息弹窗组件,类似toast
  59. showClose: true,
  60. message: res.data.error.message.message
  61. ? res.data.error.message.message
  62. : res.data.error.message,
  63. type: "error"
  64. });
  65. return Promise.reject(res.data.error.message);
  66. }
  67. return res;
  68. },
  69. error => {
  70. // 用户登录的时候会拿到一个基础信息,比如用户名,token,过期时间戳
  71. // 直接丢localStorage或者sessionStorage
  72. if (!window.localStorage.getItem("loginUserBaseInfo")) {
  73. // 若是接口访问的时候没有发现有鉴权的基础信息,直接返回登录页
  74. router.push({
  75. path: "/login"
  76. });
  77. } else {
  78. // 若是有基础信息的情况下,判断时间戳和当前的时间,若是当前的时间大于服务器过期的时间
  79. // 乖乖的返回去登录页重新登录
  80. let lifeTime =
  81. JSON.parse(window.localStorage.getItem("loginUserBaseInfo")).lifeTime *
  82. 1000;
  83. let nowTime = new Date().getTime(); // 当前时间的时间戳
  84. console.log(nowTime, lifeTime);
  85. console.log(nowTime > lifeTime);
  86. if (nowTime > lifeTime) {
  87. Message({
  88. showClose: true,
  89. message: "登录状态信息过期,请重新登录",
  90. type: "error"
  91. });
  92. router.push({
  93. path: "/login"
  94. });
  95. } else {
  96. // 下面是接口回调的satus ,因为我做了一些错误页面,所以都会指向对应的报错页面
  97. if (error.response.status === 403) {
  98. router.push({
  99. path: "/error/403"
  100. });
  101. }
  102. if (error.response.status === 500) {
  103. router.push({
  104. path: "/error/500"
  105. });
  106. }
  107. if (error.response.status === 502) {
  108. router.push({
  109. path: "/error/502"
  110. });
  111. }
  112. if (error.response.status === 404) {
  113. router.push({
  114. path: "/error/404"
  115. });
  116. }
  117. }
  118. }
  119. // 返回 response 里的错误信息
  120. let errorInfo = error.data.error ? error.data.error.message : error.data;
  121. return Promise.reject(errorInfo);
  122. }
  123. );
  124. // 对axios的实例重新封装成一个plugin ,方便 Vue.use(xxxx)
  125. export default {
  126. install: function(Vue, Option) {
  127. Object.defineProperty(Vue.prototype, "$http", { value: Axios });
  128. }
  129. };

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

  1. import Vue from "vue";
  2. import Router from "vue-router";
  3. import layout from "@/components/layout/layout";
  4. // 版块有点多,版块独立路由管理,里面都是懒加载引入
  5. import customerManage from "./customerManage"; // 客户管理
  6. import account from "./account"; //登录
  7. import adManage from "./adManage"; // 广告管理
  8. import dataStat from "./dataStat"; // 数据统计
  9. import logger from "./logger"; // 日志
  10. import manager from "./manager"; // 管理者
  11. import putonManage from "./putonManage"; // 投放管理
  12. import error from "./error"; // 服务端错误
  13. import { Message } from "element-ui";
  14. Vue.use(Router);
  15. // 请跳过这一段,看下面的
  16. const router = new Router({
  17. hashbang: false,
  18. mode: "history",
  19. routes: [
  20. {
  21. path: "/",
  22. redirect: "/adver",
  23. component: layout,
  24. children: [
  25. ...customerManage,
  26. ...adManage,
  27. ...dataStat,
  28. ...putonManage,
  29. ...manager,
  30. ...logger
  31. ]
  32. },
  33. ...account,
  34. ...error
  35. ]
  36. });
  37. // 路由拦截
  38. // 差点忘了说明,不是所有版块都需要鉴权的
  39. // 所以需要鉴权,我都会在路由meta添加添加一个字段requireLogin,设置为true的时候
  40. // 这货就必须走鉴权,像登录页这些不要,是可以直接访问的!!!
  41. router.beforeEach((to, from, next) => {
  42. if (to.matched.some(res => res.meta.requireLogin)) {
  43. // 判断是否需要登录权限
  44. if (window.localStorage.getItem("loginUserBaseInfo")) {
  45. // 判断是否登录
  46. let lifeTime =
  47. JSON.parse(window.localStorage.getItem("loginUserBaseInfo")).lifeTime *
  48. 1000;
  49. let nowTime = (new Date()).getTime(); // 当前时间的时间戳
  50. if (nowTime < lifeTime) {
  51. next();
  52. } else {
  53. Message({
  54. showClose: true,
  55. message: "登录状态信息过期,请重新登录",
  56. type: "error"
  57. });
  58. next({
  59. path: "/login"
  60. });
  61. }
  62. } else {
  63. // 没登录则跳转到登录界面
  64. next({
  65. path: "/login"
  66. });
  67. }
  68. } else {
  69. next();
  70. }
  71. });
  72. export default router;

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

  1. export default {
  2. // 请求地址
  3. url: "/user",
  4. // 请求类型
  5. method: "get",
  6. // 请根路径
  7. baseURL: "http://www.mt.com/api",
  8. // 请求前的数据处理
  9. transformRequest: [function(data) {}],
  10. // 请求后的数据处理
  11. transformResponse: [function(data) {}],
  12. // 自定义的请求头
  13. headers: { "x-Requested-With": "XMLHttpRequest" },
  14. // URL查询对象
  15. params: { id: 12 },
  16. // 查询对象序列化函数
  17. paramsSerializer: function(params) {},
  18. // request body
  19. data: { key: "aa" },
  20. // 超时设置s
  21. timeout: 1000,
  22. // 跨域是否带Token
  23. withCredentials: false,
  24. // 自定义请求处理
  25. adapter: function(resolve, reject, config) {},
  26. // 身份验证信息
  27. auth: { uname: "", pwd: "12" },
  28. // 响应的数据格式 json / blob /document /arraybuffer / text / stream
  29. responseType: "json",
  30. // xsrf 设置
  31. xsrfCookieName: "XSRF-TOKEN",
  32. xsrfHeaderName: "X-XSRF-TOKEN",
  33.  
  34. // 下传和下载进度回调
  35. onUploadProgress: function(progressEvent) {
  36. Math.round(progressEvent.loaded * 100 / progressEvent.total);
  37. },
  38. onDownloadProgress: function(progressEvent) {},
  39.  
  40. // 最多转发数,用于node.js
  41. maxRedirects: 5,
  42. // 最大响应数据大小
  43. maxContentLength: 2000,
  44. // 自定义错误状态码范围
  45. validateStatus: function(status) {
  46. return status >= 200 && status < 300;
  47. },
  48. // 用于node.js
  49. httpAgent: new http.Agent({ keepAlive: true }),
  50. httpsAgent: new https.Agent({ keepAlive: true }),
  51.  
  52. // 用于设置跨域请求代理
  53. proxy: {
  54. host: "127.0.0.1",
  55. port: 8080,
  56. auth: {
  57. username: "aa",
  58. password: "2123"
  59. }
  60. },
  61. // 用于取消请求
  62. cancelToken: new CancelToken(function(cancel) {})
  63. };

总结

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

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

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号