為何捐款
API 瀏覽器
升級指南
新功能!
quasar.config 檔案
將專案轉換為搭配 Vite 的 CLI
瀏覽器相容性
支援 TypeScript
目錄結構
命令列表
CSS 預處理器
路由
懶加載 - 代碼分割
處理資源
啟動檔案
預取功能
API 代理
處理 Vite
處理 process.env
使用 Pinia 的狀態管理
使用 Vuex 的狀態管理
Linter
測試與稽核
開發行動應用程式
Ajax 請求
開放開發伺服器給公眾
Quasar CLI with Vite - @quasar/app-vite
SSR 處理 404 和 500 錯誤

SSR 上的 404 & 500 錯誤處理方式與其他模式(例如 SPA)略有不同。如果您查看 /src-ssr/middlewares/render.js,您會注意到以下章節

/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 範例中,請注意,如果網路伺服器遇到任何渲染錯誤,我們會將一個簡單的字串傳回客戶端('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/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>`)