在AdonisJS中结合Playwright生成PDF时的DOM访问问题求助
问题分析与解决方案
错误原因
page.evaluate() 的回调函数运行在 Playwright 启动的浏览器页面上下文中,而非 AdonisJS 的 Node.js 服务端环境。你在服务端导入的 JSDOM 是 Node.js 专属库,浏览器环境中不存在这个模块,因此抛出 ReferenceError: JSDOM is not defined。
同时你的代码逻辑存在冗余:已经通过 page.setContent(html) 将渲染好的 HTML 加载到了浏览器页面中,完全不需要再用 JSDOM 重新解析一遍 HTML。
修复后的代码
直接在 page.evaluate() 中使用浏览器原生的 document 和 window 对象即可:
import { inject } from '@adonisjs/core' import { HttpContext } from '@adonisjs/core/http' import { chromium } from 'playwright' import { ConfigPdfInteface } from '../interface/config_pdf_interface.js' @inject() export default class PlaywrightService { constructor(protected ctx: HttpContext) {} async generatePdfPlaywright( response: HttpContext['response'], path: string, documents: any, config: ConfigPdfInteface ) { try { const browser = await chromium.launch({ headless: true, }) const page = await browser.newPage() await page.emulateMedia({ media: 'print' }) const html = await this.ctx.view.render(`${path}`, documents) await page.setContent(html, { waitUntil: 'networkidle', }) const selector = '#someSelector' // 直接使用浏览器原生DOM API const bodySize = await page.evaluate((selector) => { const body = document.querySelector(selector) if (!body) return null return window.getComputedStyle(body).minHeight }, selector) console.log('bodySize', bodySize) const pdfBuffer = await page.pdf(config) await browser.close() response.header('Content-type', 'application/pdf') response.header('Content-Disposition', 'inline; filename=example.pdf') response.send(pdfBuffer) } catch (error) { console.error(error) response.status(500).send('PDF Error') } } }
TypeScript DOM 类型支持
如果需要在编写 page.evaluate() 回调时获得 DOM 类型提示,可执行以下步骤:
- 安装 DOM 类型依赖:
npm install --save-dev @types/dom
- 修改
tsconfig.json,在compilerOptions.lib中添加"dom":
{ "compilerOptions": { "lib": ["ESNext", "dom"] } }
内容的提问来源于stack exchange,提问作者Izlia
相关产品推荐
相关产品推荐

