未被捕获(承诺中)NavigationDuplicated错误,无效凭证

时间:2019-10-24 11:06:07

标签: vuejs2 promise

在我的Laravel 5.8中/“ vue”:“ ^ 2.6.10” /“ vuex”:“ ^ 3.1.0” app在resources / js / components / Login.vue文件中,我有方法

methods: {
    authenticate() {
        this.$store.dispatch('login');    // calling action

        login(this.$data.form)
            .then((res) => {

                this.$store.commit("setLoginSuccess", res);  // calling mutation
                this.$store.dispatch('retrieveHostelBookmarks', res.user.id);
                this.$store.dispatch('retrievePersonalOptions', res.user.id);


                this.$router.push({path: '/personal'}); // For debugging!
            })
            .catch((error) => {
                console.log("=== error::")
                console.log(error)
                this.$store.commit("setLoginFailed", {error});   // calling mutation
            });
    }

以及在resources / js / helpers / authFuncs.js中,我有定义:

export function login(credentials) {
    return new Promise((res, rej) => {
        axios.post('/api/auth/login', credentials)
            .then((response) => {
                setAuthorizationToken(response.data.access_token);
                res(response.data);
            })
            .catch((err) =>{
                console.error(err)
                rej("Wrong email or password");
            })
    })
}

问题是在控制台中的无效凭据上,我在输出末尾看到promise警告:

VM836:1 POST http://127.0.0.1:8084/api/auth/login 401 (Unauthorized)
(anonymous) @ VM836:1
dispatchXhrRequest @ app.js?dt=1571914585:311
xhrAdapter @ app.js?dt=1571914585:150
dispatchRequest @ app.js?dt=1571914585:758
Promise.then (async)
request @ app.js?dt=1571914585:560
Axios.<computed> @ app.js?dt=1571914585:585
...
app.js?dt=1571914585:10042 === error::
app.js?dt=1571914585:10043 Wrong email or password
app.js?dt=1571914585:131483 Uncaught (in promise) NavigationDuplicated {_name: "NavigationDuplicated", name: "NavigationDuplicated", message: "Navigating to current location ("/login") is not allowed", stack: "Error↵    at new NavigationDuplicated (http://127.…/127.0.0.1:8084/js/app.js?dt=1571914585:148080:12"}

为什么这个警告以及如何解决?

6 个答案:

答案 0 :(得分:4)

我们可以使用this.$router.push(route, () => {});来消除错误。

答案 1 :(得分:2)

我刚刚在Vue JS SPA应用程序中遇到了这个问题,因为它在页面加载后立即请求GET /api/user,这会导致错误401过期的JWT令牌。

我看不到它们发生的顺序,但我可以看到首先运行中间件,然后运行axios.interceptors.response.use(response => response, (error) => {})

两个人都在呼叫this.$route.push({ name: 'login' })。在拦截器运行期间,路由更改已在进行中。

我的解决方案是保留中间件的this.$route.push({ name: 'login' }),然后将拦截器更改为:

import router from '~/router';

...

if (router.currentRoute.name !== 'login') {
    router.push({ name: 'login' }).catch(() => {});
}

我选择根据路由名称进行匹配,以免对/login进行硬编码。如果拦截器检查由于令牌过期而应执行的操作,则如果登录路由已在加载中,它将有效地跳过可能重复的路由更改。

答案 2 :(得分:1)

您不能有router-link指向当前链接。看到这个Github issue

我建议您在重定向之前检查router-link是否指向当前链接,请参见下面的代码

if (this.$router.path !== '/login') {
    this.$router.push('/login')
}

如果路由器路径不是/login,则需要重定向。希望我的回答对您有所帮助。

答案 3 :(得分:0)

已修改#2: 我发现WHERE错误已触发!在我的resources / js / app.js中,我有:

const router = new VueRouter({
    routes,
    mode: 'history'
});

checkAuthorization(store, router);
axios.interceptors.response.use(null, (error) => {

    if (error.response.status == 401) {

        store.commit('setLogout');

        console.log("0012 route.path::")
        console.log( $route )      // THAT OUTPUTS NOTHING
        console.log( $route.path ) // THAT OUTPUTS NOTHING

        router.push('/login');  // THAT RISE ERROR !
    }

    return Promise.reject(error);
});


const app = new Vue({
    el: '#app',
    router,
    store,
    bus,
    components: {
        mainapp, appheader, appfooter, navigation
    },
});


router.afterEach(( to, from ) => {
    bus.$emit('page_changed', from, to);
});

和行

router.push('/login');

引发此错误,但我不知道如何检查当前路径

我提供的链接已阅读:

  

注意:$ route是vue-router提供给每个组件的对象

但是$ route为空。我想我需要在

内获取$ route.path
axios.interceptors.response.use

如何?

已修改#3: 我试图包裹在try块中

try {
    router.push('/login');
}
catch(error) {
    console.log("0014 route.path::")
}

但是还是出现错误... 有任何决定吗?

答案 4 :(得分:0)

看起来像是简单的决定,因为error.response引用了当前页面:

if ( error.response.config.url != '/api/auth/login' ) {
    router.push('/login');
}

对我有用...

答案 5 :(得分:0)

最简单的解决方案

this.$router.push('/something').catch(err => { return err })