使用vuex在vue/axios中进行全局http响应错误处理 [英] Global http response error handling in vue/axios with vuex

查看:591
本文介绍了使用vuex在vue/axios中进行全局http响应错误处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试解决vue SPA中的一种行为,该行为基本上是一种不稳定状态,其中应用程序不知道JWT已经过期,因此呈现出好像用户仍在登录的状态.(这种情况发生在例如休眠)

I'm trying to fix a behavior in my vue SPA which is basically a limbo state where the app doesn't know the JWT is already expired and therefore presents itself as if the user was still logged in. (this happens after hibernation for example)

这些用户可以继续向API发出任意请求,但最终会得到401响应

These users can keep on making any request to the API, but end up with a 401 response of course

现在,我想为401响应提供一个全局处理程序. (这将是:从vuex清除与用户相关的所有内容,并以用户为访客的身份显示页面,并带有登录表单弹出窗口等"),否则我将不得不为每个请求编写一个401处理程序

Now I would like to have a global handler for 401 responses. (which would be: "clear everything user-related from vuex and present the page as if the user was a guest, with login form popup etc"), otherwise i would have to write a 401 handler for EVERY request

问题是: 我可以将响应拦截器添加到axios,并且它们可以正常工作. 但 他们无权访问vuex(或Vue).

the problem being: I can add response interceptors to axios, and they work fine. BUT they don't have access to vuex (or Vue).

每当我尝试将vuex或Vue导入到我的axios中时,我都会得到循环依赖(当然),并且一切都会中断.

Whenever i try to import vuex or Vue into my axios, i get circular dependencies (of course) and everything breaks.

如果我只是抛出/返回错误,我仍然必须在每次请求时单独处理它.

If i just throw/return the error, i will STILL have to handle it separately on every request.

(更多信息:) axios文件包含export default class API

(more info:) the axios file contains an export default class API

通过以下方式在main.js中全局添加到Vue:

which is added to Vue globally in main.js via

import api from 'Api/api'
// ...
Vue.prototype.$http = api

所以我认为必须有一种从$http访问Vue的方法,因为这是一个全局实例方法...我错了吗?

so i thought there has to be a way to access Vue from $http, since, it's a global instance method... am I wrong?

我该如何解决?

main.js

// ...
import api from 'Api/api'
// ...
Vue.prototype.$http = api

new Vue({
  el: '#app',
  router,
  store,
  template: '<App/>',
  components: { App },
  vuetify: new Vuetify(opts),
});

api.js

import Client from './ApiClient'

const apiClient = new Client({ basePath: process.env.VUE_APP_API_URL })

const api = {
  get(url) {
    return apiClient._get(`${basePath}/${url}`)
  },
  post(url, data) {
    return apiClient._post(`${basePath}/${url}`, data)
  },
  // ...
}
export default api

ApiClient.js

const axios = require('axios')

const errorHandler = (error) => {
  if (error.response.status === 401) {
    store.dispatch('user/logout') // here is the problem
  }
  return Promise.reject({ ...error })
}


export default class API {
  constructor(options) {
    this.options = Object.assign({ basePath: '' }, options)
    this.axios = axios.create({ timeout: 60000 })
    this.axios.interceptors.response.use(
      response => response,
      error => errorHandler(error)
    )
  }
  // ...
}

更新

在ApiClient.js中导入存储会导致依赖周期.我真的不知道为什么,但是我想是因为我要在其中导入Vue?

update

importing store in ApiClient.js results in a dependency cycle. i don't really know why, but i assume because i'm importing Vue in it?

store.js

import Vue from 'vue'
import Vuex from 'vuex'
import PersistedState from 'vuex-persistedstate'
import CreateMutationsSharer from 'vuex-shared-mutations';
import SecureLS from 'secure-ls';
// import modules

Vue.use(Vuex);
const ls = new SecureLS({ encodingType: 'aes' });

export default new Vuex.Store({
  // options
})

如果您需要更多信息,请询问:)

If you need any more info, just ask :)

感谢您的帮助

推荐答案

main.js:

import store from './store';

const Instance = new Vue({
  store,
  ...
})

export const { $store } = Instance;

现在,您可以在任意位置import { $store } from '@/main.js'.而且它将是您在应用程序中安装的同一实例,而不是new Vuex.Store({})(每次将其导入其他地方时,都是./store导出的内容).

Now you can import { $store } from '@/main.js' anywhere you want. And it's going to be the same instance you have mounted in your app, not a new Vuex.Store({}) (which is what ./store exports, each time you import it somewhere else).

您可以使用与服务,测试,帮助程序等中可能要使用的其他任何东西相同的方式导出.即:

You can export the same way anything else you might want to use in services, tests, helpers, etc... I.e:

export const { $store, $http, $bus, $t } = Instance;

这篇关于使用vuex在vue/axios中进行全局http响应错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆