vuex를 사용하는 vue/axios에서 글로벌 http 응답 오류 처리
VueJS SPA에서 림보 상태가 발생하는 동작을 수정하려고 합니다.앱은 JWT가 이미 만료된 것을 알지 못하기 때문에 사용자가 아직 로그인한 것처럼 표시됩니다.예를 들어, 이는 최대 절전 모드 이후에 발생할 수 있습니다.
이러한 사용자는 API에 대한 모든 요청을 계속 할 수 있지만, 최종적으로는401
응답(올바른 응답)
글로벌 핸들러를 원합니다.401
응답합니다.(이는 "vuex에서 사용자 관련 모든 것을 지우고 사용자가 게스트인 것처럼 로그인 폼팝업 등을 통해 페이지를 표시"하는 것입니다).그렇지 않으면 모든 요구에 대해 401 핸들러를 작성해야 합니다.
공리에 반응 가로채기를 추가할 수 있고, 잘 작동합니다.그러나 이 요격기들은 Vuex(또는 Vue)에 액세스할 수 없습니다.
Vuex 또는 Vue를 Axios로 Import하려고 할 때마다 순환 종속성이 발생하고 모든 것이 중단됩니다.
에러를 폐기/반환하는 것만으로, 모든 요구에 대해 개별적으로 대응해야 합니다.악시오스 인터셉터 내에서 메서드를 디스패치하려면 어떻게 해야 합니까?
Axios 파일에는export default class API
Vue에 글로벌하게 추가되어 있습니다.main.js
:
import api from 'Api/api'
// ...
Vue.prototype.$http = api
난 다른 사람들과의 접촉이 가능할 거라고 생각했었어Vue
부터$http
글로벌 인스턴스 방식이기 때문에.하지만 내가 틀린 것 같아?
코드
main.discloss.main.discloss.
// ...
import api from 'Api/api'
// ...
Vue.prototype.$http = api
new Vue({
el: '#app',
router,
store,
template: '<App/>',
components: { App },
vuetify: new Vuetify(opts),
});
api.module
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)
)
}
// ...
}
스토어 Import처ApiClient.js
의존 사이클이 발생합니다.Vue를 수입하기 때문에 그런 것 같아요?
store.displaces를 설정합니다.
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
})
main.filename:
import store from './store';
const Instance = new Vue({
store,
...
})
export const { $store } = Instance;
이제 할 수 있다import { $store } from '@/main.js'
당신이 원하는 곳 아무데나.이 인스턴스는 어플리케이션에 마운트된 인스턴스와 동일합니다.new Vuex.Store({})
(그게 바로./store
다른 장소에서 Import 할 때마다 exports(내보냅니다.
서비스, 테스트, 도우미 등에서 사용할 수 있는 다른 모든 항목을 동일한 방법으로 내보낼 수 있습니다.예:
export const { $store, $http, $bus, $t } = Instance;
이 스레드를 기반으로 요구에 맞는 솔루션을 관리할 수 있었습니다.
main.discloss.main.discloss.
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 파일을 나중에 확장할 수 있는 구성이 필요합니다.
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
});
ApiClient.js에 스토어를 직접 Import하는 것은 어떻습니까?뭐랄까
const axios = require('axios')
import store from 'path/to/store'
const errorHandler = (error) => {
if (error.response.status === 401) {
store.dispatch('user/logout') // now store should be accessible
}
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)
)
}
// ...
}
언급URL : https://stackoverflow.com/questions/61613545/global-http-response-error-handling-in-vue-axios-with-vuex
'programing' 카테고리의 다른 글
size of ( )를 사용하지 않고 이 코드를 사용하여 어레이 크기를 결정하는 방법 (0) | 2022.07.17 |
---|---|
로거 스태틱파이널을 선언하는 이유는 무엇입니까? (0) | 2022.07.17 |
C에서 파일을 잘라내는 방법 (0) | 2022.07.17 |
C/C++ 기본형은 원자형입니까? (0) | 2022.07.17 |
VueJs의 구성 요소에 개체 또는 개체 키 전달 (0) | 2022.07.17 |