我正在尝试修复VueJS SPA中出现的一种行为,其中出现了一种不稳定状态。应用程序不知道JWT已经过期,因此呈现出用户仍在登录的样子。例如,这可能发生在Hibernate之后。
这些用户可以继续向API发出任何请求,但最终会得到401
响应(这是正确的)。
我想要一个401
响应的全局处理程序。(这将是:从vuex清除所有与用户相关的内容,并将页面呈现为用户是访客,并弹出登录表单等。)否则,我将不得不为每个请求编写401处理程序。
我可以将响应拦截器添加到axios,它们工作得很好。不过,这些拦截器无法访问Vuex(或Vue)。
每当我尝试将Vuex或Vue导入Axios时,我都会得到循环依赖(当然),一切都会中断。
如果我只是抛出/返回错误,我仍然必须在每个请求上分别处理它。如何在上分派方法$是否从axios拦截器中存储
?
Axios文件包含一个导出默认类API
,该API在main中全局添加到Vue中。js
:
import api from 'Api/api'
// ...
Vue.prototype.$http = api
我认为必须有一种方法从$超文本传输协议
访问Vue
,因为它是一个全局实例方法。但我似乎搞错了?
主要的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?
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
})
conf
import Axios from 'axios'
import IdentityProxy from './IdentityProxy.js'
import UsuariosProxi from './UsuariosProxi'
import ZonasProxi from './ZonasProxi'
//axios
Axios.defaults.headers.common.Accept='application/json'
//Axios.defaults.headers.common['Access-Control-Allow-Origin'] = '*';
Axios.interceptors.request.use(
config => {
let token = localStorage.getItem('access_token');
if(token){
config.headers= {
'x-access-token': `${token}`
}
}
return config;
},
error => Promise.reject(error)
);
Axios.interceptors.response.use(
response => response,
error => {
if (error.response.status===403||error.response.status===401) {
localStorage.removeItem('access_token');
window.location.reload(true);
}
return Promise.reject(error);
}
);
let url=null
if(localStorage.getItem("config")!==null){
let config = JSON.parse(localStorage.getItem("config"))
url = config
}
console.log(url)
export default{
identityProxy: new IdentityProxy(Axios, url),
_usuarioProxi: new UsuariosProxi(Axios, url),
_zonasProxi: new ZonasProxi(Axios, url),
}
//
export default class IdentityProxy{
constructor(axios,url){
this.axios = axios;
this.url =url;
}
register(params){
return this.axios.post(this.url+'/identity/register',params)
}
login(params){
return this.axios.post(this.url+'/auth/signin',params)
}
}
//
export default class UsuariosProxi{
constructor(axios,url){
this.axios = axios;
this.url =url;
}
/* getAll(){
return this.axios.get(this.url+'/users')
} */
getAll(page, take) {
return this.axios.get(this.url + `/users?page=${page}&take=${take}`);
}
create(params) {
return this.axios.post(this.url + '/auth/signup', params);
}
get(id) {
return this.axios.get(this.url + `/users/${id}`);
}
update(id, params) {
return this.axios.put(this.url + `/users/${id}`, params);
}
remove(id) {
return this.axios.delete(this.url + `/users/${id}`);
}
//-----APARTE SOLO TRAE LISTA DE ROLES--------
getRoles() {
return this.axios.get(this.url + '/users/newrol');
}
}
//st
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const state = {
user:null
}
export default new Vuex.Store({
state
});
基于这些线程,我能够根据自己的需要管理解决方案:
主要的js
import api, {apiConfig} from 'Api/api'
apiConfig({ store: $store });
ApiClient.js
let configs = {
store: undefined,
};
const apiConfig = ({ store }) => {
configs = { ...configs, store };
};
export default api;
export { apiConfig };
这样就可以创建api。js文件将需要一个以后可以扩展的配置。
主要的js:
import store from './store';
const Instance = new Vue({
store,
...
})
export const { $store } = Instance;
现在您可以从'@/main'导入{$store}。js'
任何你想要的地方。它将是您在应用程序中安装的同一个实例,而不是新的Vuex。Store({})(这就是每次在其他地方导入时,/Store
导出的内容)。
您可以以同样的方式导出您可能希望在服务、测试、帮助程序等中使用的任何其他内容。。。即:
export const { $store, $http, $bus, $t } = Instance;
问题内容: 我想全局拦截某些错误情况,以防止控制器自己处理错误。我认为我需要HTTP拦截器,但是我不确定如何从我的控制器中处理错误。 我有一个像这样的控制器: 和这样的HTTP拦截器: 这与浏览器重定向到“ /错误”路径一样有效。但在承诺抓的 也 执行了,我不希望这样。 我知道我可以编写代码,使其忽略404错误,但这是无法维护的。假设我进行修改以同时处理500个错误,那么我将不得不再次进行修改(以
不想每个axios请求都写错误判断,所以在axios进行响应拦截,判断是否有请求错误,如果出现400、401错误会用antdv的message.error提示错误信息 测试时,会出现首次访问页面,如返回400、401错误,信息不自动提示的问题,另外使用console.log()打印错误信息却能正常使用,是不是message组件的问题?
我有一个自定义过滤器,它在使用Spring Cloud Gateway调用实际API之前对每个请求进行身份验证。Spring Cloud中有没有像Spring提供@ControllerAdvision那样集中处理异常的方法?我希望全局处理异常,并从网关返回自定义错误响应。
这几个月来,我们一直在努力实现这一目标,但现在需要这样做。我需要显示服务器上设置的错误消息,说明出现了什么错误: 服务器endpoint 网状物: 在chrome开发工具中的预览下,我看到消息
错误响应 状态:400 消息:“用户ID和密码错误” 在这里,我可以获得或处理成功数据,但不能获得或处理错误数据,因为在catch函数中,只有错误对象被传递,而错误对象只包含来自服务器的响应代码,而不是响应数据
我正在使用Apollo与用React编写的Web应用程序中的GraphQL服务器进行交互。我试图在应用程序中实现错误处理,并依赖于apollo-link-error。 现在,我需要处理两类错误: 可以在执行Apollo查询或变异的组件中本地处理的错误,即需要在其上显示上下文错误信息的无效表单字段 可以全局处理的错误,例如,通过在页面的某个位置显示toast通知来显示错误详细信息 显然,一旦错误在本