Vue多组件重复报错信息的优化问题

发布于 2022-09-11 23:27:00 字数 2412 浏览 9 评论 0

image.png

先上图,大概情况就是这个样:

系统有多个组件,比如User组件主要控制用户信息的显示,需要调用获取用户数据的接口,主页面Main组件负责展示主要页面数据,也要调接口,页面上有个选择系统用户的组件,也要走接口获取数据,整个系统是通过JWT进行鉴权的,鉴权是以中间键的形式卸载在后端服务中的,所以有时候JWT过期了就会出现如图所示的情况。

多个组件多个接口都报错,就会出现多个error提示。

http工具用的axios,ui用的iview,有没有大佬有优化这个问题的思路,就是只用弹一个错误提示就行了,劳烦提点一下。

import axios from 'axios'
import storage from './storage'
import { Message } from 'iview'
import router from '@/router'

axios.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  config.headers.Authorization = 'Bearer ' + storage.get('token')
  return config
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

axios.interceptors.response.use(function (response) {
  // 对响应数据做点什么
  if (response.headers.authorization) {
    storage.set('token', response.headers.authorization.substr(7))
  }
  return response
}, function (error) {
  // 对响应错误做点什么
  switch (error.response.status) {
    case 401:
      Message.error(error.response.data.msg)
      router.replace(`/login?next=${encodeURIComponent(location.hash.substr(1))}`)
      break
    case 403:
      return Promise.resolve(error.response)
    default:
      return Promise.reject(error)
  }
})

export default axios
const jwt = require('jsonwebtoken')
const whiteList = [
  '/api/auth/login',
  '/api/auth/logout',
  '/api/auth/qrcode'
]
const config = require('../config')

module.exports = async (ctx, next) => {
  if (whiteList.indexOf(ctx.path) === -1) {
    // 验证jwt是否过期
    await jwt.verify(ctx.headers.authorization.substr(7), config.jwtSecret, async (err, decoded) => {
      if (err) {
        if (err.name === 'TokenExpiredError') {
          // token已过期,抛出401
          ctx.status = 401
          ctx.body = {
            code: '-1',
            msg: '登录状态已过期,请重新登录'
          }
        } else {
          ctx.status = 401
          ctx.body = {
            code: '-1',
            msg: 'token验证失败' + err.name,
            err: JSON.stringify(err)
          }
        }
      } else {
        ctx.user = decoded.user
        // 没有过期
        await next()
        // 重新签发一个新的token
        let token = jwt.sign({ user: decoded.user }, config.jwtSecret, {expiresIn: 600})
        ctx.set('Authorization', 'Bearer ' + token)
      }
    })
  } else {
    await next()
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

很快妥协 2022-09-18 23:27:00

思路就是全局存个是否已经弹出过错误提示了,每次弹之前判断一下。

// 这行:
Message.error(error.response.data.msg);
// 改成:
const blockingKey = '_isAxiosMessageShowing';
if (sessionStorage.getItem(blockingKey) !== 'true') {
    sessionStorage.setItem(blockingKey, 'true');
    Message.error({
        content: error.response.data.msg,
        onClose: () => {
            sessionStorage.removeItem(blockingKey);
        }
    });
}

示例里用了 sessionStorage,至于你想用 vuex 还是挂载成 Vue 或 axios 的全局属性,随你意。

余生一个溪 2022-09-18 23:27:00

采纳了 @然后去远足 大佬的答案,

case 401:
      // Message.error(error.response.data.msg)
      const msgKey = 'Error401Message'
      if (storage.get(msgKey) !== 'true') {
        storage.set(msgKey, 'true')
        Message.error({
          content: error.response.data.msg,
          onClose: () => {
            storage.remove(msgKey)
          }
        })
      }
      router.replace(`/login?next=${encodeURIComponent(location.hash.substr(1))}`)
      break
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文