javascript - Vue.js:如何从拦截器代表组件发出请求?
问题描述
在我的 Vue 应用程序中,我有一个响应拦截器:
axios.interceptors.response.use(function (config) {
return config;
}, error => {
if (error.response.status !== 401) {
return new Promise((resolve, reject) => {
reject(error);
});
}
if (error.response.status === 401 && error.response.data.message === 'Token Expired') {
this.store.dispatch('auth/refreshToken').then(aToken => {
var config = error.config;
axios.defaults.headers.common['Authorization'] = 'Bearer ' + aToken;
return new Promise((resolve, reject) => {
axios.request(config).then(response => {
console.log(response);
resolve(response);
}).catch((error) => {
reject(error);
});
});
});
}
});
...我正在刷新令牌并使用新令牌再次发出最后一个(拦截的)请求。
但问题是,假设我有一个组件,当组件安装时,我在其中向端点Product.vue
发出请求。/products
我将所有产品存储在products
该组件的数据变量中。想象一下用户现在在/dashboard
路线中。他去喝了一口咖啡,等他回来的时候,令牌已经过期了。他访问/products
路由,响应为 401,因此拦截器拦截该响应,更新令牌,然后尝试使用新令牌发出最后一个失败的请求。
但是这个新请求不是从Product
组件执行的。它是从拦截器执行的,我无法访问该Product
组件。因此,尽管请求成功,但我的响应数据丢失了,最终用户将在视图中看不到任何内容,因为products
变量为空。
有没有办法跟踪哪个组件执行了请求并将其重新安装在拦截器中?我试过$router.push('/products')
但 vue 抛出一个异常,指出不允许导航到当前路线。
或者,有什么方法可以处理从 Product 组件中的拦截器返回的承诺?
解决方案
您需要做的就是保持承诺链运行。目前,您因不返回调度承诺而失去了它。
axios.interceptors.response.use(success => success, error => {
if (error.response.status === 401 && error.response.data.message === 'Token Expired') {
// return the new promise
// not sure what "this" is or why "store" is in it but hey, it's your code
return this.store.dispatch('auth/refreshToken').then(token => {
axios.defaults.headers.common.Authorization = `Bearer ${token}`
return axios.request(error.config)
})
}
return Promise.reject(error)
})
解释一下,Axios 的响应拦截器将自己插入到请求创建的承诺链中。.then()
把它们想象成在您的调用代码接收数据之前在请求的末尾添加一个额外的......
return axios.request({ ... })
.then(successInterceptor)
.catch(errorInterceptor)
在您的代码中,您不关心成功的响应,因此您只需返回原始响应
success => success
然后,您的错误拦截器会检查过期的令牌响应并返回一个新的承诺,该承诺以更新令牌开始,然后重复原始请求(请参阅Promise 链接)。
如果响应错误不是针对过期令牌,您只需通过返回拒绝的承诺来维持错误状态。如果你不这样做,被拒绝的承诺就会变成一个成功的承诺,这会让你的调用代码非常混乱。
推荐阅读
- python - Python discord bot 跳过代码或停止工作
- python - 运行 sys.meta_path[2].find_distributions() 时出现 Python OSError(pytest 需要)
- mongodb - Mongodb 使用嵌套查找聚合复杂文档
- vue.js - VueJS 前端/管理屏幕
- python - Python嵌套字典通过特定子键访问
- reactive-programming - Quarkus 叛变 - 缺少对 Web 客户端的 OAuth2 支持
- jestjs - Jest & React 测试库:如何访问 getAllByText() 的元素
- python-3.x - [SSL:CERTIFICATE_VERIFY_FAILED]
- reactjs - 如何存储日期选择器中的日期?
- ubuntu - 在 Ubuntu 服务器上通过 composer 安装 Magento 最新版本时出现问题