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

在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 类型提示,可执行以下步骤:

  1. 安装 DOM 类型依赖:
npm install --save-dev @types/dom
  1. 修改 tsconfig.json,在 compilerOptions.lib 中添加 "dom":
{
  "compilerOptions": {
    "lib": ["ESNext", "dom"]
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 02:25:06