如何在使用 axios 发出的所有 HTTP 请求之前发出请求?



我将 VueJS 与 axios 和 Vuex 一起使用。对于我向 API 发出的每个请求,我始终需要在 URL 之前发出请求以获取数据。

这是我的初始代码,但它对我不起作用。事实上,浏览器挂断了。

import Vue from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
import store from './store'
import router from './router'
[...]
Vue.use(VueAxios, axios)
[...]
axios.defaults.baseURL = 'http://API_URL/api/v1'
axios.defaults.headers.get['Accept'] = 'application/json'
axios.defaults.headers.common['Content-Type'] = 'application/json'
axios.interceptors.request.use(req => {
if (store.state.user.user != null) {
req.headers['Authorization'] = `Bearer ${store.state.user.user.jwtToken}`
// INTERCEPTOR
axios.get('http://OTHER_URL/verify_expire_token')
.then(res => {
if (res.data.response === 'error') {
router.push('/')
}
})
}
return req
})

在我的actions.js(对于我的模块user(中,我有我所有的HTTP请求,例如getUserInfo

import axios from 'axios'
import router from '@/router'
export default {
[...]
async getUserInfo ({ state, commit }, item) {
axios.get('/users/info/' + item.codeUser)
.then(res => {
commit('setBasicInfo', res.data) // Set a state
})
.catch(err => console.log(err))
},
[...]
}

但是在我在某些组件中使用此操作并调用 API/users/info/之前,我需要调用http://OTHER_URL/verify_expire_token。 这就是为什么在我的 axios 初始值设定项中我在请求中放置了一个拦截器。

最好的方法是什么?

最好创建自己的ApiHandler.js文件来单独处理所有远程内容,并且可以轻松地从任何地方调用,包括 vue 组件和 vuex。

这是它的外观(未测试或检查错误或拼写错误(

<script>
import axios from 'axios';
class ApiHandler{
constructor(apiUrl) {
this.axios = axios;
this.apiUrl = apiUrl || '';  // this line allow passing a custom endpoint for testing
this.config = {
headers: { 'Cache-Control': 'no-cache' },  // can setup to prevent all caching
baseURL: this.apiUrl,
};
}
verifyToken() {
// this assumes you are storing the token in your local store, of course this can come from anywhere
let token = window.localStorage.getItem('token');
// this assumes same api server, but you could handle that by having two different this.config objects
return new Promise((resolve, reject) => {
this.axios.get('/verifyToken', { token }, this.config)
.then((response) => {
// example of handling a custom API response
if (response.code === 200) {
resolve(true);
} else {
reject('Bad token');
}
})
.catch((err) => {
reject('internal error');
});
});
// alternatively, you can skip creation of a new promise and just use `return this.axios.get`
// this will not allow you to handle an error in a message with a success header (some APIs be like that)
}
getInfo(userId) {
let payload = { userId }; // in case you need to pass data
// chan promise requests, start by calling verify token
return new Promise((resolve, reject) => {
this.verifyToken()
.then(() => {
// then do the next call
return this.axios.get('/users/info', {}, this.config)
})
.then((userInfo) => {
// check if data is valid (see if it hase a name field or some other check if you like)
if (userInfo && userInfo.name) {
resolve(userInfo)
} else {
// return some error specific to request
reject('User does not exist');
}
})
.catch((err) => {
reject(err);
});
});
}
}
</script>

然后,您可以通过以下方法从任何地方调用此名称...

<script>
import ApiHandler from '../lib/ApiHandler';
const apiRequest = new ApiRequest();
// and then anywhere in the component
apiRequest.getInfo(112)
.then((userInfo)=>{
this.$set(this, 'userData', userData);
})
.catch(err => {
if (typeof err === 'string'){
this.errorMessage = err;
} else {
console.error(err);
}
})
</script>

如您所见,我正在使用自定义 Promise 处理程序来使用我自己的resolvereject函数,您可以跳过这些并简化结构。

即使我展示的是用于组件的,我也会使用操作进一步抽象它。该组件将调用一个操作,该操作将调用 apiHandler,该操作会在响应时将新数据推送到 vuex 存储中,这将在使用该数据的所有组件上触发更新(通过 vuex getters(。

最新更新