Puppeteer调用fileChooser上传文件无响应无报错问题
Puppeteer文件上传失效排查与解决思路
问题复现
手动触发网站上传入口时,可正常弹出文件选择提示,效果如下:
执行自动化代码时程序无报错,但上传逻辑未生效,页面无任何上传相关反馈,执行后效果如下:
问题代码片段:
let visa_file = 'C:\Users\birbara2\Desktop\DubaiReal\residence.png'; const [fileChooser] = await Promise.all([ page.waitForFileChooser(), page.click('#file-drop-zone'), // 触发文件选择的按钮 ]); await fileChooser.accept([visa_file]);
触发上传的目标元素HTML结构:
<div tabindex="0"><input accept="image/png,image/jpeg,application/pdf" multiple="" type="file" autocomplete="off" tabindex="-1" style="display: none;"><p>Edict Document</p></div>
排查与解决思路
- 优先修复文件路径转义错误
Windows系统路径中的反斜杠\是JavaScript的转义字符,原代码中直接写单斜杠的路径会被解析为带无效转义字符的错误路径,Puppeteer读取不到对应文件时不会抛出显式错误,直接修改路径写法即可:// 两种修正写法二选一 let visa_file = 'C:\\Users\\birbara2\\Desktop\\DubaiReal\\residence.png'; let visa_file = 'C:/Users/birbara2/Desktop/DubaiReal/residence.png'; - 绕过自定义上传组件的点击校验
从DOM结构可以看出,实际承载文件选择能力的是内部设置了display: none的input[type=file]元素,外层div是自定义的上传交互区域,很多这类自定义组件会校验点击事件的isTrusted属性(判断是否为用户真实手动触发),自动化模拟点击外层div无法触发隐藏input的文件选择弹窗。这种场景不需要等待fileChooser事件,直接定位到隐藏的file input元素调用上传方法即可:// 定位隐藏的文件输入框直接上传 const fileInput = await page.$('input[type=file]'); await fileInput.uploadFile(visa_file); - 补全元素加载等待逻辑
如果上传组件是页面加载完成后异步渲染的,直接操作元素时可能还未绑定完成上传事件,需要添加显式等待,确保DOM节点已渲染:// 等待文件输入框DOM渲染完成,因元素本身是隐藏状态,visible参数设为false await page.waitForSelector('input[type=file]', {visible: false}); const fileInput = await page.$('input[type=file]'); await fileInput.uploadFile(visa_file); - 手动触发change事件唤醒组件回调
部分自定义上传组件不会自动监听input的赋值动作,直接调用uploadFile后不会触发后续上传逻辑,需要在文件赋值完成后手动派发change事件,触发组件的上传回调:await page.waitForSelector('input[type=file]', {visible: false}); const fileInput = await page.$('input[type=file]'); await fileInput.uploadFile(visa_file); // 手动派发冒泡的change事件 await page.evaluate(() => { const input = document.querySelector('input[type=file]'); input.dispatchEvent(new Event('change', { bubbles: true })); });
内容的提问来源于stack exchange,提问作者birb
相关产品推荐
相关产品推荐

