到目前为止,我一直在每个想要进行HTTP请求的Vue组件中导入axios,就像这样。
<script lang="ts">
import axios from 'axios';
@Component
export default class ExamplePage extends Vue {
created(): void {
axios.post(some_path);
}
}
然而,现在我想为所有 axios 请求定义一个全局拦截器,基本上是为了捕获后端服务器(Rails)返回的所有
401未授权
响应并注销用户。 我目前的理解是您必须实例化 axios 一次并在各处使用它,而不是在每个文件中导入和使用不同的实例。我参考了这个和这个,并尝试了以下方法。
// application.js
import '../assets/sass/base.sass';
import App from '../app';
import Vue from 'vue';
import VueRouter from 'vue-router';
import axios from 'axios';
import router from '../routes';
Vue.use(VueRouter);
document.addEventListener('DOMContentLoaded', () => {
new Vue({
el: '#application',
router,
render: (h) => h(App),
});
});
axios.interceptors.response.use(
response => response,
error => {
const status = error.response;
if(status === 401) {
// do stuff
}
}
);
Vue.prototype.$http = axios
当我尝试在另一个文件中调用
this.$http.put(...)
时,它显示属性$http
不存在(我猜测这是因为那个组件上下文中的this
是组件本身,但我不确定)。我该如何解决这个问题?
[更新] 感谢您的回复,我决定在一个单独的文件中初始化axios实例,然后使用它。然而,这仍然无法正常工作。401响应似乎根本没有触发拦截器。是否需要进行其他配置?
// axios-instance.ts
import axios, { AxiosInstance } from 'axios';
const axiosInstance: AxiosInstance = axios.create();
axiosInstance.interceptors.response.use(
response => response.data,
async function(error) {
console.log("THIS IS THE 401 INTERCEPTOR")
const status = error.response;
if(status === 401) {
// Log out user
}
}
);
export default axiosInstance;
// Some component
<script lang="ts">
import axiosInstance from 'axios-instance';
@Component
export default class ExamplePage extends Vue {
created(): void {
axiosInstance.post(some_path);
}
}
application.js
中写this.$http.interceptors
,必须使用axios.interceptors
。如果这不是问题的原因,请更新您的问题以包含未正常工作的put
调用。没有一些上下文,很难确定您是否正确执行了这个操作。 - skirtleconst status = error.response;
,这应该是const status = error.response.status;
。错误处理程序也没有返回拒绝的承诺,这可能会带来问题。 - skirtle