【问题标题】:How to check if a page exist in a custom server using Next.js如何使用 Next.js 检查自定义服务器中是否存在页面
【发布时间】:2020-05-02 03:15:21
【问题描述】:

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

我尝试使用 app.router.execute,但它总是返回 false。所以我想这不是办法。我检查了 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)
})

【问题讨论】:

  • 我知道这不是一个优雅的解决方案,但是检查 response.statusCode 怎么样?基本上你对当前路线发出请求并检查状态码。
  • 我尝试了res.end 事件。但是看起来在状态 200 之后使用 301 重定向会出错:Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
  • 我的意思是像这样var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl; fetch(fullUrl).then((res) => { status = res.status; console.log( res.status ) }).catch((err) => { // handle error for example console.error(err); }); 还要注意,这个检查不应该在server.get('*' 内部进行,因为它会检查所有请求(css,imgs,ecc ...)而不是你应该仅在路线内部进行此检查。

标签: javascript node.js reactjs express next.js


【解决方案1】:

我终于解决了:

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)
})

如果有人知道更优雅的解决方案,将受到欢迎。

【讨论】:

  • 目前这不是最好的解决方案,因为它不适用于动态路由
【解决方案2】:

这个可怕的 hack 并没有在调用 handle 之前严格告诉您路由是否存在,但它确实让您在下次向 res 呈现任何内容之前挂钩并应用您自己的 404 错误自定义处理。

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);
    }
};

【讨论】:

    猜你喜欢
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 2011-04-24
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    相关资源
    最近更新 更多