You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

迁移场景下:如何用Express将Next.js输出转为指定JSON格式

在Express.js中包装Next.js生成的内容为指定JSON格式

方案一:拦截响应流收集HTML内容

通过重写Express响应对象的write和end方法,收集Next.js输出的所有内容块,最后将拼接后的HTML包装成JSON返回。

实现代码

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

const port = 8080;
const dev = process.env.NODE_ENV !== 'production';

const nextApp = next({dev});
const handle = nextApp.getRequestHandler();

// 响应拦截中间件:收集HTML内容并包装为JSON
function captureHtmlResponse(req, res, next) {
  // 过滤静态资源请求(如Next.js的/_next/资源、图片、JS/CSS文件),只处理页面请求
  if (req.path.startsWith('/_next/') || req.path.match(/\.(js|css|png|jpg|svg|ico)$/)) {
    return next();
  }

  const originalEnd = res.end;
  const contentChunks = [];

  // 重写write方法,收集所有输出的内容块
  res.write = function(chunk) {
    contentChunks.push(Buffer.from(chunk));
    return true; // 返回true表示写入成功
  };

  // 重写end方法,将收集到的HTML包装为JSON返回
  res.end = function(chunk) {
    if (chunk) {
      contentChunks.push(Buffer.from(chunk));
    }
    const fullHtml = Buffer.concat(contentChunks).toString('utf8');
    // 设置正确的响应头
    res.setHeader('Content-Type', 'application/json');
    // 发送包装后的JSON
    originalEnd.call(this, JSON.stringify({ content: fullHtml }));
  };

  next();
}

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

  // 先挂载拦截中间件,再处理Next.js请求
  server.use(captureHtmlResponse);

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

  server.listen(port, () => {
    console.log(`[server]: Server is running at http://localhost:${port}`);
  });
});

方案二:直接调用Next.js的renderToHTMLAPI

通过Next.js提供的renderToHTML方法主动获取页面渲染后的HTML字符串,再包装成JSON返回,无需拦截响应流,逻辑更直接可控。

实现代码

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

const port = 8080;
const dev = process.env.NODE_ENV !== 'production';

const nextApp = next({dev});
const handle = nextApp.getRequestHandler();

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

  server.all('*', async (req, res) => {
    try {
      // 解析当前请求的路径和查询参数
      const { pathname, query } = nextApp.getRequestHandler().parse(req);
      // 调用renderToHTML获取页面渲染后的HTML
      const pageHtml = await nextApp.renderToHTML(req, res, pathname, query);
      // 返回包装后的JSON
      res.json({ content: pageHtml });
    } catch (error) {
      // 处理渲染错误(如页面不存在),交给Next.js默认处理逻辑
      handle(req, res);
    }
  });

  server.listen(port, () => {
    console.log(`[server]: Server is running at http://localhost:${port}`);
  });
});

注意事项

  • 方案二的renderToHTML会自动处理页面的服务器端数据获取逻辑(如getServerSideProps),和原Next.js请求行为一致
  • 若需过滤静态资源,可在路由处理中添加路径判断,跳过静态资源的JSON包装

内容的提问来源于stack exchange,提问作者chrgue

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 07:25:28