From b9c163fd0645cd20331e1ff46cece7c2f773c303 Mon Sep 17 00:00:00 2001 From: UnknownMp Date: Fri, 2 May 2025 22:54:47 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20404=20=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.js | 26 +++++++++++++++++++++----- src/entry-client.js | 9 +++++++-- src/entry-server.js | 19 ++++++++++++++----- src/main.js | 5 +---- src/router.js | 3 ++- 5 files changed, 45 insertions(+), 17 deletions(-) diff --git a/server.js b/server.js index 45fc17c..ad89ddc 100644 --- a/server.js +++ b/server.js @@ -16,6 +16,11 @@ const templateHtml = isProduction const app = express() app.use(cookieParser()); +const MESSAGE = { + 404: 'Not Found', + 0: 'Unknown' +} + // Add Vite or respective production middlewares /** @type {import('vite').ViteDevServer | undefined} */ let vite @@ -42,19 +47,30 @@ app.use('*all', async (req, res) => { /** @type {string} */ let template /** @type {import('./src/entry-server.js').render} */ - let render + let render, getRoute if (!isProduction) { // Always read fresh template in development template = await fs.readFile('./index.html', 'utf-8') template = await vite.transformIndexHtml(url, template) - render = (await vite.ssrLoadModule('/src/entry-server.js')).render + const module = await vite.ssrLoadModule('/src/entry-server.js') + render = module.render + getRoute = module.getRoute } else { template = templateHtml - render = (await import('./dist/server/entry-server.js')).render + const module = await import('./dist/server/entry-server.js') + render = module.render + getRoute = module.getRoute } - const { stream, piniaState } = await render(url, req.cookies, req.headers.host) + const { router, code } = await getRoute(url) + if (code != 200 && !req.accepts('html')) { + res.status(code).set({ 'Content-Type': 'text/plain' }) + res.write(MESSAGE[code] || MESSAGE[0]) + res.end() + return + } + const { stream, piniaState } = await render(router, req.cookies, req.headers.host) const [htmlStart, htmlEnd] = template.split('') - res.status(200).set({ 'Content-Type': 'text/html' }) + res.status(code).set({ 'Content-Type': 'text/html' }) res.write(htmlStart) for await (const chunk of stream) { if (res.closed) break diff --git a/src/entry-client.js b/src/entry-client.js index 5c60e48..c8f9555 100644 --- a/src/entry-client.js +++ b/src/entry-client.js @@ -1,8 +1,13 @@ import { decompress } from 'compress-json' import './main.css' -import { createApp } from './main' -const { app, pinia, router } = createApp() +import { createApp } from './main' +import { createSSRRouter } from './router.js' + +const { app, pinia } = createApp() +const router = createSSRRouter() + +app.use(router) if (window.__PINIA_STATE__) { pinia.state.value = decompress(window.__PINIA_STATE__) diff --git a/src/entry-server.js b/src/entry-server.js index 4fdd8ca..fb02bc2 100644 --- a/src/entry-server.js +++ b/src/entry-server.js @@ -1,19 +1,28 @@ import { renderToWebStream, renderToString } from 'vue/server-renderer' import { createApp } from './main' -export async function render(_url, cookies, host) { - const { app, pinia, router } = createApp() +import { createSSRRouter } from './router.js' + +export async function getRoute(_url) { + const router = createSSRRouter() await router.push(_url) await router.isReady() + const route = router.currentRoute.value.matched[0] + const code = route.meta.code || 200 + return { router, code } +} + +export async function render(router, cookies, host) { + const { app, pinia } = createApp() + + app.use(router) const ctx = { cookies, host, initialState: {} } - // await new Promise((resolve) => setTimeout(resolve, 0)) const stream = renderToWebStream(app, ctx) - const initialState = ctx.initialStat const piniaState = pinia.state.value - return { stream, initialState, piniaState } + return { stream, piniaState } } diff --git a/src/main.js b/src/main.js index e54cda2..2c732e2 100644 --- a/src/main.js +++ b/src/main.js @@ -2,19 +2,16 @@ import { createSSRApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' -import { createSSRRouter } from './router.js' import ClientOnly from './ssr/ClientOnly.vue' import Hr from './ui/BetterHr.vue' export function createApp() { const app = createSSRApp(App) - const router = createSSRRouter() const pinia = createPinia() app.use(pinia) - app.use(router) app .component('ClientOnly', ClientOnly) .component('Hr', Hr) - return { app, pinia, router } + return { app, pinia } } diff --git a/src/router.js b/src/router.js index c5ebc27..484e727 100644 --- a/src/router.js +++ b/src/router.js @@ -41,7 +41,8 @@ export function createSSRRouter() { component: () => import('./views/fallback/NotFound.vue'), meta: { title: "页面未找到", - hidden: true + hidden: true, + code: 404 } } ]})