搭配 Webpack 的 Quasar CLI - @quasar/app-webpack
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')
}
})
})
}
content_paste
上述區段是在擷取其他可能的請求 (例如針對 /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') }
content_paste
錯誤 500
在頁面頂端的 /src-ssr/middlewares/render.js
範例中,請注意,如果網路伺服器遇到任何渲染錯誤,我們會將簡單的字串 (‘500 | Internal Server Error’) 送回用戶端。如果您想要改為顯示美觀的頁面,您可以
- 在
/src/router/routes.js
中新增特定路由,例如
{ path: 'error500', component: () => import('pages/Error500.vue') }
content_paste
- 撰寫 Vue 元件來處理此頁面。在此範例中,我們建立
/src/pages/Error500.vue
- 然後在
/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!
}
content_paste
警告
唯一的注意事項是,您需要確定在渲染 '/error500' 路由時,不會發生另一個 500 錯誤,這會使您的應用程式陷入無限迴圈!
避免這種情況的完美方法是直接從 /src-ssr/middlewares/render.js
傳回錯誤 500 頁面的 HTML (字串)。
res.status(500).send(`<html>....</html>`)
content_paste