使用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
相关产品推荐
相关产品推荐

