pie*_*reb 37 http-status-code-404 vue.js vue-router
我正在尝试重定向到使用router.beforeEach全局挂钩未找到的页面上的404.html ,但没有太大成功(使用Vue和Vue-Router1.0):
router.beforeEach(function (transition) {
    if (transition.to.path === '/*') {
        window.location.href = '/404.html'
    } else {
        transition.next()
    }
});
Run Code Online (Sandbox Code Playgroud)
404.html插入不存在的路径时,这不会重定向到页面,只是给我一个空片段.只有在硬编码some-site.com/*时,它才会重定向到预期的some-site.com/404.html
我确信这里有一些非常明显的东西,我忽略了,但我无法弄清楚是什么.
请注意,我正在寻找的是重定向到新页面,而不是重定向到另一个路由,这可以通过使用router.redirect这些片段轻松实现:
router.redirect({
    '*': '404'
})
Run Code Online (Sandbox Code Playgroud)
在我身上router.map,我可以拥有以下内容:
 router.map({
    '/404': {
        name: '404'
        component: {
            template: '<p>Page Not Found</p>'
        }
    }
})
Run Code Online (Sandbox Code Playgroud)
    Man*_*ani 83
我认为您应该能够使用默认路由处理程序并从那里重定向到应用程序外部的页面,详情如下:
const ROUTER_INSTANCE = new VueRouter({
    mode: "history",
    routes: [
        { path: "/", component: HomeComponent },
        // ... other routes ...
        // and finally the default route, when none of the above matches:
        { path: "*", component: PageNotFound }
    ]
})
Run Code Online (Sandbox Code Playgroud)
在上面的PageNotFound组件定义中,您可以指定实际的重定向,它将完全带您离开应用程序:
Vue.component("page-not-found", {
    template: "",
    created: function() {
        // Redirect outside the app using plain old javascript
        window.location.href = "/my-new-404-page.html";
    }
}
Run Code Online (Sandbox Code Playgroud)
您可以created如上图所示mounted挂钩,也可以挂钩.
请注意:
我还没有验证上面的内容.您需要构建应用程序的生产版本,确保发生上述重定向.您无法对此进行测试,vue-cli因为它需要服务器端处理.
通常在单页应用程序中,服务器会发送相同的index.html以及所有路由请求的应用程序脚本,尤其是在您已设置的情况下<base href="/">./404-page.html除非您的服务器将其视为特殊情况并提供静态页面,否则这将失败.
如果有效,请告诉我!
小智 19
@mani 的回复现在有点过时了,因为在使用 Vue 3 以后不再支持使用包罗万象的'*'路由。如果这不再适合您,请尝试用
{ path: '/:pathMatch(.*)*', component: PathNotFound },
Run Code Online (Sandbox Code Playgroud)
从本质上讲,您应该能够替换'*'路径'/:pathMatch(.*)*'并顺利进行!
原因: Vue Router 不再使用path-to-regexp,而是实现了自己的解析系统,允许路由排名并启用动态路由。由于我们通常为每个项目添加一个单一的包罗万象的路由,因此支持 *.
(来自https://next.router.vuejs.org/guide/migration/#removed-star-or-catch-all-routes)
@mani 的原始答案就是你想要的,但如果你也想以官方方式阅读它,这里是
https://router.vuejs.org/guide/essentials/history-mode.html#caveat
小智 5
这个答案可能来得有点晚,但我已经找到了一个可以接受的解决方案。我的方法有点类似于@Mani,但我认为我的方法更容易理解。
将其放入全局钩子和组件本身并不理想,全局钩子会检查每个请求,因此您需要编写大量条件来检查它是否应该为 404,并且window.location.href在组件创建中为时已晚,因为请求已进入组件已经存在,然后将其取出。
我所做的是为 404 页面提供一个专用的 url,并*为所有未找到的内容提供一个路径。
{ path: '/:locale/404', name: 'notFound', component: () => import('pages/Error404.vue') },
{ path: '/:locale/*', 
  beforeEnter (to) {
    window.location = `/${to.params.locale}/404`
  }
}
Run Code Online (Sandbox Code Playgroud)
您可以忽略,:locale因为我的网站正在使用 i18n,这样我就可以确保 404 页面使用正确的语言。
顺便说一句,我想确保我的 404 页面在找不到页面时返回 httpheader 404 状态代码而不是 200。上面的解决方案只会将您发送到 404 页面,但您仍然会收到 200 状态代码。为此,我的 nginx 规则会在位置返回 404 状态代码/:locale/404
server {
    listen                      80;
    server_name                 localhost;
    error_page  404 /index.html;
    location ~ ^/.*/404$ {
      root   /usr/share/nginx/html;
      internal;
    }
    location / {
      root   /usr/share/nginx/html;
      index  index.html index.htm;
      try_files $uri $uri/ @rewrites;
    }
    location @rewrites {
      rewrite ^(.+)$ /index.html last;
    }
    location = /50x.html {
      root   /usr/share/nginx/html;
    }
}
Run Code Online (Sandbox Code Playgroud)
        小智 5
path: "*"已经过时了。它属于vue-router3上的vue-router2。您可以使用以下命令捕获所有 404 错误页面
/:pathMatch(.*)*
Run Code Online (Sandbox Code Playgroud)
效果很好。