我正在尝试修复VueJS单页应用程序中出现的不良行为,即出现临时状态。应用程序不知道JWT已经过期,因此呈现给用户的界面仍然显示为登录状态。例如,在休眠后这种情况可能会发生。
这些用户可以继续向API发送任何请求,但最终会收到401响应(这是正确的)。
我想为401响应编写一个全局处理程序。(即:“从vuex中清除所有与用户相关的内容,并像访客一样呈现页面,包括登录表单弹窗等。”)否则,我就必须为每个请求编写401处理程序。
我可以将响应拦截器添加到axios中,它们可以正常工作。但这些拦截器无法访问Vuex(或Vue)。
每当我尝试将Vuex或Vue导入到我的Axios中时,就会出现循环依赖关系(当然),一切都会崩溃。
如果我只是抛出/返回错误,则仍然必须在每个请求上单独处理它。如何在axios拦截器中调用this.$store中的方法?
Axios文件包含一个默认导出类API,该类在main.js中全局添加到Vue中。
这些用户可以继续向API发送任何请求,但最终会收到401响应(这是正确的)。
我想为401响应编写一个全局处理程序。(即:“从vuex中清除所有与用户相关的内容,并像访客一样呈现页面,包括登录表单弹窗等。”)否则,我就必须为每个请求编写401处理程序。
我可以将响应拦截器添加到axios中,它们可以正常工作。但这些拦截器无法访问Vuex(或Vue)。
每当我尝试将Vuex或Vue导入到我的Axios中时,就会出现循环依赖关系(当然),一切都会崩溃。
如果我只是抛出/返回错误,则仍然必须在每个请求上单独处理它。如何在axios拦截器中调用this.$store中的方法?
Axios文件包含一个默认导出类API,该类在main.js中全局添加到Vue中。
import api from 'Api/api'
// ...
Vue.prototype.$http = api
我曾经认为可以通过全局实例方法访问Vue
,因此必须有一种方法可以从$http
中访问它。但是我似乎错了?
代码
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
中导入 store 导致依赖循环:我猜测这是因为在其中导入了 Vue?
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
})