如何使用 Next.js 检查页面是否存在于自定义服务器中

How to check if a page exist in a custom server using Next.js

next@9.1.7 与带有 express 的自定义服务器一起使用。在 handle(req, res) 调用之前,我如何在我的 server.js 中知道 next.js 页面是否存在?

我试过 app.router.execute 但它总是 returns 错误。所以我想这不是办法。我检查了 Next.js 文档,但没有得到任何解决方案...有人有想法吗?

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const server = express()
const handle = app.getRequestHandler()

// ...

server.get('*', async (req, res) => {
  const { url, fixed } = fixUrl(req)

  // pageExists is always false ...
  const pageExists = await app.router.execute(req, res, req.url) 

  // Fix the url and redirect only if the page exists 
  // (to avoid redirects to 404 pages)
  if (fixed && pageExists) {
    res.redirect(301, url)
    return
  }

  handle(req, res)
})

我终于解决了:

const glob = require('glob')
const path = require('path')

// ...
const pagesDir = path.resolve(`${__dirname}/../src/pages`)
const pages = glob.sync(`${pagesDir}/**/*.js`)
  .map(p => p
    .replace(pagesDir, '')
    .replace('index.js', '')
    .replace('.js', '')
  )

// ...

server.get('*',(req, res) => {
  const { url, fixed } = fixUrl(req)

  if (fixed && pages.includes(url.split('?')[0])) {
    res.redirect(301, url)
    return
  }

  handle(req, res)
})

如果有人知道更优雅的解决方案,我们将不胜感激。

这个可怕的 hack 在调用 handle 之前并没有严格地告诉你路由是否存在,但它确实让你在 next 向 res.

const errorRenderer = app.server.renderErrorToHTML;
app.server.renderErrorToHTML = function(err, req, res, pathname, query) {
    if (res.statusCode == 404) {
        // handle the 404 however you like
        return null;
    } else {
        return errorRenderer.apply(this, arguments);
    }
};