Puppeteer仅在无头模式下无法处理SSO弹窗 非无头模式运行正常
解决方案
下面是经过验证的可解决该问题的操作步骤:
- 替换旧版无头模式为新版无头模式
Chrome 112以后推出了和有头模式行为完全一致的新版无头模式,原有headless: true对应的旧版无头模式存在大量兼容问题,是该类报错的核心诱因。修改puppeteer启动配置:
const browser = await puppeteer.launch({ headless: 'new', // 替换原来的true args : [ '--disable-popup-blocking', // 新增:关闭弹窗拦截,避免SSO弹窗被拦截 '--start-maximized', // 新增:最大化窗口,避免元素未渲染导致点击失效 `--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${await browser.version().split('/')[1]} Safari/537.36` // 自动匹配当前Chrome版本的UA,避免版本 mismatch ] }); // 新增:设置和桌面端一致的视口 await page.setViewport({ width: 1920, height: 1080 });
- 修正弹窗监听逻辑
原有逻辑先触发点击再绑定弹窗监听事件,存在事件触发早于监听绑定导致漏听的可能,需将点击操作和监听操作放入同一个Promise.all中:
const [ popup ] = await Promise.all([ page.waitForEvent('popup'), // 官方推荐的写法,比手动监听once更稳定 page.click('#button_to_open_sso_popup'), // 点击操作放在Promise.all内 ]);
- 替换弹窗导航等待逻辑
SSO弹窗加载完成的时机通常早于waitForNavigation的捕获时机,直接等待弹窗内登录表单元素加载比等待导航事件更可靠:
// 删除原有popup.waitForNavigation代码,替换为等待表单元素 await popup.waitForSelector('input[type="email"]', { timeout: 15000 }); // 后续执行输入账号密码的逻辑
- 其他排查点
如果以上操作仍未解决,可以临时关闭无头模式截图确认弹窗是否正常弹出,也可以添加page.on('popup', () => console.log('弹窗触发'))日志确认监听是否正常触发。
内容的提问来源于stack exchange,提问作者dwvn
相关产品推荐
相关产品推荐

