如何通过自定义服务器访问next.js呈现的HTML



我想在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字符串。有什么办法可以做到吗?

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

这个想法是覆盖res.end函数,以便在那里捕获渲染的HTML。棘手的部分是Next.js gzip和流响应使用的压缩库覆盖res.endhandle函数的中间某处。

压缩库是使用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函数。你可以随意操作,作为文件,或者任何你想要的东西。

最新更新