【问题标题】:In Vue and Vue Router SPA, showing 404 for a not found resource在 Vue 和 Vue Router SPA 中,显示未找到资源的 404
【发布时间】:2016-11-17 12:21:53
【问题描述】:

我在 SPA 中使用 Vue 和 Vue Router。在视图组件中,我在资源库中查询资源。如果找不到资源,我想在保留 URL 的同时显示 404 页面。

即如果我访问/foo/non-existant-id,那么应该显示一个 404 页面来代替 foo 资源的显示页面。

为了清楚起见,这里是我的路由器地图:

router.map({
  '/foo/:id': {name: 'foo-show', component: FooShowPage},

  // Utilities
  '/': { name: 'home', component: HomePage },
  '*': { name: '404', component: NotFoundPage }
})

在我的FooShowPage 中,我执行以下操作:

ready () {
  // fetch the foo from the repo (app.foos)
  app.foos.fetchById(this.$route.params.id).then(foo => {
    this.foo = foo
  }).catch(e => {
    // foo is not found show a 404 page
    // using this.$route.router.go({name: '404'}) does not work as route is a wildcard 
    console.warn(e)
  })
}

基本上它可能涉及用NotFoundPage 替换路由器视图中的FooShowPage,或者重定向到定义的404 页面,同时保持浏览器历史记录不变。

【问题讨论】:

  • 你解决了吗?我目前正在调查这个问题,提供的答案对我不起作用,因为在我从后端 API 检索结果之前我不知道哪个 id 有效
  • 我有同样的问题,但在任何地方都找不到解决方案。在我进行 api 调用并收到 404 之前,我不知道动态参数是否有效。

标签: javascript single-page-application vue.js vue-router


【解决方案1】:

找到solution at Vue.js forum——使用navigation guard

import store from '../store'

{
  path: '/lavori/:lavoro',
  name: 'lavoro',
  component: Lavoro,
  beforeEnter: (to, from, next) => {
    function isValid (id) {
      return store.getters.resourceByID(id) !== undefined
    }

    if (!isValid(to.params.id)) {
      next({ name: 'not-found' });
    }    
    next();
  }
},

Edit1:需要import store 才能访问getter,来自这个Github issue 和这个question

仍然是一个问题,如何保留相同的(请求的)URL

【讨论】:

    【解决方案2】:

    我想出的最好方法是使用带有 Axios 的全局拦截器将通过 API 接收到的所有 404 响应重定向到 404 路由。但是,这确实将 url 更改为 /404,就像@Leo 的回答一样。

    const http = axios.create({
      headers: {
        'X-Requested-With': 'XMLHttpRequest'
      }
    });
    
    // Add some global response intercepters
    http.interceptors.response.use(function (response) {
      // For successes just continue as normal
      return response;
    
    }, function (error) {
      // If we have a 404 redirect to the error page replacing the history
      if (error.response.status === 404) {
        return router.replace({ name: 'notfound' });
      }
    
      return Promise.reject(error);
    });
    
    export default http;
    

    【讨论】:

      【解决方案3】:

      您需要为 404 页面设置一个路由,然后将不匹配的路由重定向到它。我在地图之后使用router.redirect 来做这样的事情。

      router.map({
        '/': { name: 'home', component: HomePage },
        '/foo/:id': {name: 'foo-show', component: FooShowPage},
        '/404': {name: 'not-found', component: NotFound}
      })
      
      router.redirect({
          '*': '/404'
      })
      

      所有未在地图中列出的路线将被重定向到/404

      【讨论】:

      • 最好的答案,但如果我得到类似 /foo/:gibberish 的东西,它不会触发。必须在每条路线内部进行管理?像应用程序逻辑问题?我想念我的 php
      • @Cristo 使用导航守卫来处理重定向。
      猜你喜欢
      • 2016-03-23
      • 2017-03-14
      • 1970-01-01
      • 2021-01-14
      • 2020-11-07
      • 2020-06-11
      • 2019-02-13
      • 2017-03-04
      • 2021-12-29
      相关资源
      最近更新 更多