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

使用JSDOM结合polyfill获取页面内容时遇JSON循环结构错误

问题解决:Next.js接口中JSDOM循环引用导致的JSON序列化错误

错误原因

你遇到的TypeError: Converting circular structure to JSON是因为window对象包含大量循环引用属性(比如window.document指向document,document.window又指向window),JSON序列化器无法处理这种结构。同时代码里存在冗余操作:已经通过JSDOM.fromURL得到dom实例,却重复用new JSDOM(dom)创建实例,完全没必要。

修正方案

核心思路:不要直接返回window或dom对象,提取你实际需要的HTML内容,同时修正冗余的JSDOM实例创建,添加错误捕获避免未处理的Promise拒绝。

修正后的完整代码

import type { NextApiRequest, NextApiResponse } from 'next';
import matchMediaPolyfill from 'mq-polyfill';
import { JSDOM } from 'jsdom';

export default function handler(req: NextApiRequest, res: NextApiResponse) {
  const { collection } = req.query;
  
  // 校验collection格式
  if (typeof collection !== 'string' || collection.length !== 42) {
    return res.status(400).json({ error: "Collection length needs to be 42!" });
  }

  JSDOM.fromURL(`https://rarible.com/collection/${collection}`, {
    runScripts: "dangerously",
    pretendToBeVisual: true,
    resources: "usable"
  })
  .then(dom => {
    // 直接使用dom实例的window,无需重新创建JSDOM
    const window = dom.window;
    // 应用媒体查询polyfill
    matchMediaPolyfill(window);
    window.matchMedia('(min-width: 920px)');
    
    // 提取你需要的HTML内容,比如整个文档的HTML
    const pageHtml = window.document.documentElement.outerHTML;
    // 返回提取的内容,而非window对象
    res.status(200).json({ html: pageHtml });
  })
  .catch(err => {
    // 捕获请求或渲染过程中的错误
    res.status(500).json({ error: `Failed to fetch page: ${err.message}` });
  });
}

关键修改点

  • 移除冗余JSDOM实例创建:直接使用JSDOM.fromURL返回的dom实例的window属性,不需要new JSDOM(dom)
  • 避免返回循环引用对象:提取document.documentElement.outerHTML(或你需要的特定元素HTML)作为返回值,而非整个window对象
  • 增强参数校验:明确判断collection是字符串类型,避免非字符串值导致的length判断错误
  • 添加错误捕获:用.catch处理请求过程中的异常,避免unhandledRejection错误
  • 修正响应状态码:参数错误时返回400(客户端错误)而非200,符合HTTP规范

内容的提问来源于stack exchange,提问作者Ted's Projects

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:15:39