【问题标题】:How to access next.js rendered HTML via custom server如何通过自定义服务器访问 next.js 呈现的 HTML
【发布时间】:2021-02-02 16:17:43
【问题描述】:

我希望将 next.js 中的服务器端生成页面作为文件提供。所以我想在自定义 server.js 文件中获取呈现的内容:

const express = require('express');
const next = require('next');

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({dev});
const handle = app.getRequestHandler();

app.prepare().then(() => {
  const server = express();

  server.get('/', async (req, res) => {
    const nextResponse = await app.renderToHTML(req, res, '/', req.query);

    console.log('nextResponse', nextResponse);
    console.log('res.body', res.body);
  });

  server.get('*', (req, res) => {
    return handle(req, res);
  });

  server.listen(port, (err) => {
    if (err) throw err;
    console.log(`> Ready on http://localhost:${port}`);
  });
});

奇怪的是,每个 console.log 都返回 null 或 undefined。 我认为 renderToHTML 只会返回呈现的 HTML 字符串。有没有办法做到这一点?

【问题讨论】:

标签: javascript next.js server-side-rendering


【解决方案1】:

这个有点棘手,但可以实现。

这个想法是覆盖res.end 函数,以便在那里捕获呈现的HTML。棘手的部分是 Next.js 使用 compression 库压缩和流式响应响应,该库在 handle 函数中间的某处覆盖了 res.end

使用 Next.js 的 Server 对象的 handleCompression 函数初始化压缩库(可使用 app.getServer() 访问),因此该函数也需要被覆盖。

所以它应该看起来像这样:

const { parse } = require('url');
const next = require('next');
const express = require('express');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });

const port = process.env.PORT || 3000;

const handle = app.getRequestHandler();

app.prepare()
.then(() => {
    const server = express();

    server.get('*', async (req, res) => {
        const parsedUrl = parse(req.url, true);

        const nextServer = await app.getServer();
        const _handleCompression = nodeServer.handleCompression.bind(nodeServer);

        nextServer.handleCompression = (req, res) => {
            _handleCompression(req, res);

            const _resEnd = res.end.bind(res)
            res.end = function (payload) {
                console.log('Rendered HTML: ', payload);

                return _resEnd(payload);
            }
        }

        return handle(req, res, parsedUrl);
    });

    server.listen(port, err => {
        if (err) throw err;
        console.log('> Ready on http://localhost:' + port);
    });
});

在获得呈现的 HTML 后,您不必使用保存的 _resEnd 函数。随意操作、用作文件或任何你想要的东西。

【讨论】:

    猜你喜欢
    • 2019-01-01
    • 1970-01-01
    • 2021-08-18
    • 2018-01-01
    • 1970-01-01
    • 2014-12-17
    • 2020-06-29
    • 2011-05-11
    • 1970-01-01
    相关资源
    最近更新 更多