Vuejs 3 + 路由器 + Axios(带拦截器)- 忽略推送
Vuejs 3 + Router + Axios (with Interceptor) - Push ignored
我的场景是:
"axios": "^0.26.1",
"vue": "^3.2.25",
"vue-router": "^4.0.14"
我主要使用 axios 拦截器来做两件事:
- 添加一个header,并且
- 刷新令牌逻辑。
在添加 axios 拦截器的代码之前,router.push("/")
或 router.push({name:"Home"})
工作正常,但现在它们被忽略了。
我在其他威胁中读到过同样的问题,但我没有看到 solutions/workaround 在拦截器代码之外继续使用 router.push
。
我希望你能帮助我完成接下来的两件事:
- 如何更深入地调试以检查 vue 路由器中的日志?
- 如果我使用axios拦截器,我可以继续使用
router.push
命令吗?
谢谢和问候,
代码:
axios拦截器
const setup = (authStore = useAuthStore()) => {
http.interceptors.request.use(
(config: AxiosRequestConfig) => {
const token: string = authStore.getAccessToken
if (token) {
config.headers.Authorization = 'Bearer ' + token
}
return config
},
(error) => {
Promise.reject(error)
}
),
http.interceptors.response.use(
(res: AxiosResponse) => {
return res
},
async (err:AxiosError) => {
const originalConfig = err.config
if (originalConfig.url !== 'auth/login' && err.response) {
// access-token expired
if (err.response.status === 401 && !originalConfig._retry) {
originalConfig._retry = true
try {
const rs = await http.post('auth/refreshtoken/', { token: authStore.getRefreshToken })
const { accessToken } = rs.data
authStore.setAccessToken(accessToken)
return http(originalConfig)
} catch (_error) {
return Promise.reject(_error)
}
}
}
return Promise.reject(err)
}
)
}
export default setup
授权服务
import http from "../utils/http-common"
class AuthService{
login(data: FormData): Promise<any> {
return http.post("auth/login/", data, {headers: { "Content-Type": "multipart/form-data" }, timeout: 3000})
}
me(): Promise<any> {
return http.get("auth/me/")
}
}
export default new AuthService
Vue 组件
const login = async () => {
const formData = new FormData()
loading.value = true
formData.append("username", credentials.username)
formData.append("password", credentials.password)
await auth.login(formData)
.then((res:AxiosResponse) => {
authStore.setAuthenticated
authStore.setAccessToken(res.data.access_token)
authStore.setRefreshToken(res.data.refresh_token)
router.push({ name: "Home" })
})
.catch((e:AxiosError) => {
alert(e.response?.status + ' ' + e.response?.statusText)
})
.finally(() => loading.value = false)
这可能适用于你的情况,没有检查所有可能的问题
try {
const response = await auth.login(formData)
await authStore.setAuthenticated() // may not be needed if not an async Vuex action
await authStore.setAccessToken(response.data.access_token) // same
await authStore.setRefreshToken(response.data.refresh_token) // same
await router.push({ name: "Home" }) // this one is always nice because it's actually async
} catch (e) {
alert(e.response?.status + ' ' + e.response?.statusText)
}
PS: 不清楚TS,不知道怎么用(sorry)
我的场景是:
"axios": "^0.26.1", "vue": "^3.2.25", "vue-router": "^4.0.14"
我主要使用 axios 拦截器来做两件事:
- 添加一个header,并且
- 刷新令牌逻辑。
在添加 axios 拦截器的代码之前,router.push("/")
或 router.push({name:"Home"})
工作正常,但现在它们被忽略了。
我在其他威胁中读到过同样的问题,但我没有看到 solutions/workaround 在拦截器代码之外继续使用 router.push
。
我希望你能帮助我完成接下来的两件事:
- 如何更深入地调试以检查 vue 路由器中的日志?
- 如果我使用axios拦截器,我可以继续使用
router.push
命令吗?
谢谢和问候,
代码:
axios拦截器
const setup = (authStore = useAuthStore()) => {
http.interceptors.request.use(
(config: AxiosRequestConfig) => {
const token: string = authStore.getAccessToken
if (token) {
config.headers.Authorization = 'Bearer ' + token
}
return config
},
(error) => {
Promise.reject(error)
}
),
http.interceptors.response.use(
(res: AxiosResponse) => {
return res
},
async (err:AxiosError) => {
const originalConfig = err.config
if (originalConfig.url !== 'auth/login' && err.response) {
// access-token expired
if (err.response.status === 401 && !originalConfig._retry) {
originalConfig._retry = true
try {
const rs = await http.post('auth/refreshtoken/', { token: authStore.getRefreshToken })
const { accessToken } = rs.data
authStore.setAccessToken(accessToken)
return http(originalConfig)
} catch (_error) {
return Promise.reject(_error)
}
}
}
return Promise.reject(err)
}
)
}
export default setup
授权服务
import http from "../utils/http-common"
class AuthService{
login(data: FormData): Promise<any> {
return http.post("auth/login/", data, {headers: { "Content-Type": "multipart/form-data" }, timeout: 3000})
}
me(): Promise<any> {
return http.get("auth/me/")
}
}
export default new AuthService
Vue 组件
const login = async () => {
const formData = new FormData()
loading.value = true
formData.append("username", credentials.username)
formData.append("password", credentials.password)
await auth.login(formData)
.then((res:AxiosResponse) => {
authStore.setAuthenticated
authStore.setAccessToken(res.data.access_token)
authStore.setRefreshToken(res.data.refresh_token)
router.push({ name: "Home" })
})
.catch((e:AxiosError) => {
alert(e.response?.status + ' ' + e.response?.statusText)
})
.finally(() => loading.value = false)
这可能适用于你的情况,没有检查所有可能的问题
try {
const response = await auth.login(formData)
await authStore.setAuthenticated() // may not be needed if not an async Vuex action
await authStore.setAccessToken(response.data.access_token) // same
await authStore.setRefreshToken(response.data.refresh_token) // same
await router.push({ name: "Home" }) // this one is always nice because it's actually async
} catch (e) {
alert(e.response?.status + ' ' + e.response?.statusText)
}
PS: 不清楚TS,不知道怎么用(sorry)