SSR处理404和500错误

SSR上404和500错误的处理方式与其他模式(例如SPA)略有不同。 如果您检查/src-ssr/index.js(这是您的生产版本WEB服务器),则会注意到以下部分:

// 这应该是最后的get(),使用SSR渲染
app.get('*', (req, res) => {
  res.setHeader('Content-Type', 'text/html')
  ssr.renderToString({ req, res }, (err, html) => {
    if (err) {
      if (err.url) {
        res.redirect(err.url)
      }
      else if (err.code === 404) {
        res.status(404).send('404 | Page Not Found')
      }
      else {
        // 渲染错误页面或重定向
        res.status(500).send('500 | Internal Server Error')
        if (ssr.settings.debug) {
          console.error(`500 on ${req.url}`)
          console.error(err)
          console.error(err.stack)
        }
      }
    }
    else {
      res.send(html)
    }
  })
})

上面的部分是在捕获其他可能的请求(如/statics文件夹、manifest.json和service worker等)之后编写的。 这是我们初始化您的应用的地方,您的路由器和Vue也会渲染您请求的页面。

要注意的事情

我们将讨论您需要注意的一些体系结构决策。 选择最适合您的应用的内容。

错误404

如果您在Vue路由/src/router/routes.js文件中定义了等效的404路由(如下所示),则上述示例中的if (err.code === 404) {永远不会是 true,因为Vue Router已经处理了它。

// 使用Vue路由捕获404的路由示例
{ path: '*', component: () => import('pages/error404.vue') }

为了获得最佳性能和服务器负载,建议避免使用Vue路由配置404页面,而让SSR生产版本Web服务器处理它。 在您的/src/router/routes.js中,您可以优先仅针对非SSR模式捕获404,如下所示:

// 假设您有一个“routes”数组
if (process.env.MODE !== 'ssr') {
  routes.push({
    path: '*',
    component: () => import('pages/error404.vue')
  })
}

错误500

On the /src-ssr/index.js example at the top of the page, notice that if the webserver encounters any rendering error, we send a simple string back to the client (‘500 | Internal Server Error’). If you want to show a nice page instead, you could: 在页面顶部的/src-ssr/index.js示例中,请注意,如果web服务器遇到任何呈现错误,我们会向客户端发送一个简单的字符串(“500 | Internal Server Error”)。 如果要显示一个漂亮的页面,则可以:

  1. /src/router/routes.js中添加特定的路由,例如:
{ path: 'error500', component: () => import('pages/Error500.vue') }
  1. 编写Vue组件以处理此页面。 在这个例子中,我们创建/src/pages/Error500.vue
  2. 然后在/src-ssr/index.js中:
if (err.url) { ... }
else if (err.code === 404) { ... }
else {
  // 这里我们获得500错误;
  // 我们将重定向到在步骤#1中新定义的“error500”路由。
  res.redirect('/error500')
}

WARNING

唯一值得注意的是,您需要确保在渲染“/error500”路由时不会再出现500错误,这会使您的应用陷入无限循环!

避免这种情况的理想方法是直接从/src-ssr/index.js返回错误500页面的HTML(作为String):

res.status(500).send(`<html>....</html>`)