为什么捐赠
API 资源管理器
升级指南
NEW!
quasar.config 文件
转换为使用 Webpack 的 CLI
浏览器兼容性
支持 TypeScript
目录结构
命令列表
CSS 预处理器
路由
延迟加载 - 代码分割
处理资产
引导文件
预取功能
API 代理
处理 Webpack
处理 process.env
使用 Pinia 进行状态管理
使用 Vuex 进行状态管理
代码规范检查
测试 & 审计
开发移动应用
Ajax 请求
向公众开放开发服务器
Quasar CLI 与 Webpack - @quasar/app-webpack
SSR 处理 404 和 500 错误

在 SSR 模式下,处理 404 和 500 错误与其他模式(如 SPA)略有不同。 如果你查看 /src-ssr/middlewares/render.js,你会注意到以下部分

export default ({ app, resolve, render, serve }) => {
  // we capture any other Express route and hand it
  // over to Vue and Vue Router to render our page
  app.get(resolve.urlPath('*'), (req, res) => {
    res.setHeader('Content-Type', 'text/html')

    render({ req, res })
      .then(html => {
        // now let's send the rendered html to the client
        res.send(html)
      })
      .catch(err => {
        // oops, we had an error while rendering the page

        // we were told to redirect to another URL
        if (err.url) {
          if (err.code) {
            res.redirect(err.code, err.url)
          }
          else {
            res.redirect(err.url)
          }
        }
        // hmm, Vue Router could not find the requested route
        else if (err.code === 404) {
          // Should reach here only if no "catch-all" route
          // is defined in /src/routes
          res.status(404).send('404 | Page Not Found')
        }
        // well, we treat any other code as error;
        // if we're in dev mode, then we can use Quasar CLI
        // to display a nice error page that contains the stack
        // and other useful information
        else if (process.env.DEV) {
          // serve.error is available on dev only
          serve.error({ err, req, res })
        }
        // we're in production, so we should have another method
        // to display something to the client when we encounter an error
        // (for security reasons, it's not ok to display the same wealth
        // of information as we do in development)
        else {
          // Render Error Page on production or
          // create a route (/src/routes) for an error page and redirect to it
          res.status(500).send('500 | Internal Server Error')
        }
      })
  })
}

上面的部分是在捕获其他可能的请求(如 /public 文件夹、manifest.json 和 service worker 等)之后编写的。 这是我们使用 Vue 和 Vue Router 渲染页面的地方。

需要注意的事项

我们将讨论一些需要了解的架构决策。 选择最适合你的应用程序的方案。

错误 404

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

// Example of route for catching 404 with Vue Router
{ path: '/:catchAll(.*)*', component: () => import('pages/Error404.vue') }

错误 500

在页面顶部的 /src-ssr/middlewares/render.js 示例中,请注意,如果 Web 服务器遇到任何渲染错误,我们将向客户端发送一个简单的字符串('500 | 内部服务器错误')。 如果你想显示一个漂亮的页面,你可以:

  1. /src/router/routes.js 中添加一个特定的路由,例如
{ path: 'error500', component: () => import('pages/Error500.vue') }
  1. 编写处理此页面的 Vue 组件。 在此示例中,我们创建 /src/pages/Error500.vue
  2. 然后在 /src-ssr/middlewares/render.js
if (err.url) { ... }
else if (err.code === 404) { ... }
else {
  // We got a 500 error here;
  // We redirect to our "error500" route newly defined at step #1.
  res.redirect(resolve.urlPath('error500')) // keep account of publicPath though!
}

警告

唯一的注意事项是,你需要确保在渲染 '/error500' 路由时不会遇到另一个 500 错误,这会导致你的应用程序陷入无限循环!

避免这种情况的最佳方法是直接从 /src-ssr/middlewares/render.js 返回错误 500 页面的 HTML(作为字符串)。

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