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

Puppeteer多窗口操作出现Target closed错误的原因及解决

Puppeteer 19.0.0 多窗口操作后出现「Target closed」错误的排查与解决

错误原因分析

  1. 异步回调残留触发:多窗口操作时,新页面的CDP(Chrome DevTools Protocol)会话可能残留未完成的异步回调,调用browser.close()断开连接时,这些回调会因目标已关闭抛出错误。这类错误在事件循环微任务中触发,常规try/catch无法捕获。
  2. 页面关闭逻辑冲突:手动遍历关闭所有页面后,browser.close()会再次尝试处理已关闭的页面,导致Puppeteer内部状态不一致,触发错误。
  3. 新页面引用管理不当:打开新窗口时未正确追踪页面实例,或操作后未妥善关闭,导致Puppeteer持有无效页面引用,清理阶段触发错误。

解决办法

1. 优化销毁方法,避免重复操作

Puppeteer调用browser.close()时会自动关闭所有页面,无需手动遍历。若必须手动关闭页面,需为每个操作添加错误捕获:

public async destroy() {
    let browserIsConnected: boolean = !!this._browser?.isConnected();
    if (this._browser && browserIsConnected) {
        try {
            const pages = await this._browser.pages();
            for (let pg of pages) {
                try {
                    this.logger.debug(`Closing page ${pg.url()}`);
                    // 强制关闭,忽略已关闭页面的错误
                    await pg.close({ force: true });
                } catch (e) {
                    this.logger.debug(`Skip closed page: ${pg.url()}`);
                }
            }

            this.logger.debug(`Closing browser instance...`);
            // 移除所有事件监听,避免残留回调触发错误
            this._browser.removeAllListeners();
            await this._browser.close();
            this.logger.log(`Closed browser connection`);
        } catch (e) {
            this.logger.error(`Cleanup error: ${e}`);
        } finally {
            delete this._browser;
        }
    } else {
        this.logger.log(`Browser already destroyed`);
        delete this._browser;
    }
}

2. 规范多窗口操作的页面生命周期

打开新窗口时,必须通过waitForTarget正确获取页面实例,操作完成后及时关闭:

// 监听新页面创建
const newPagePromise = this._browser.waitForTarget(
    target => target.type() === 'page' && !target.url().startsWith('about:blank')
);
// 触发打开新窗口的操作(如点击链接)
await mainPage.click('a[target="_blank"]');
// 获取新页面实例
const newPage = await newPagePromise;

// 执行新页面操作
await newPage.waitForSelector('#target-element');
// ...其他业务逻辑

// 操作完成后关闭新页面
await newPage.close();

3. 升级Puppeteer版本

Puppeteer 19.0.0存在多窗口处理的已知bug,升级到20.x及以上版本可修复多数此类问题。

4. 过滤全局异步未捕获错误

针对异步抛出的「Target closed」错误,可在代码入口添加全局监听避免测试失败:

process.on('unhandledRejection', (reason) => {
    // 过滤目标关闭错误,不影响测试结果
    if (reason?.toString().includes('Target closed')) return;
    console.error('Unhandled Rejection:', reason);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:55:30