如何使用Puppeteer重写showOpenFilePicker并在其调用前执行自定义函数
如何用Puppeteer重写showOpenFilePicker并在调用前执行自定义函数
没问题,我们可以沿用你提供的toBlob重写思路,但要注意showOpenFilePicker是直接挂载在window对象上的全局方法,而非某个DOM元素的原型方法,所以重写的目标对象会不一样。
核心思路是:先保存原生函数的引用,再用自定义逻辑包裹它——这样既可以在调用前执行你的自定义代码,又不会破坏原函数的功能。
以下是完整的实现代码:
const puppeteer = require("puppeteer"); (async () => { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); await page.evaluateOnNewDocument(() => { // 先保存原生showOpenFilePicker的引用,避免覆盖后丢失原功能 const originalShowOpenFilePicker = window.showOpenFilePicker; // 重写全局的showOpenFilePicker方法 window.showOpenFilePicker = async (...args) => { // ******** 这里是你的自定义前置逻辑 ******** console.log("触发自定义前置函数:showOpenFilePicker即将被调用!"); // 你可以在这里添加任何操作,比如日志记录、参数修改、甚至拦截调用 // 调用原生函数并返回结果,保证原有文件选择功能正常工作 return originalShowOpenFilePicker.apply(window, args); }; }); await page.goto("https://example.com"); // 测试:在页面中主动调用showOpenFilePicker,验证前置逻辑是否执行 await page.evaluate(async () => { console.log("页面脚本开始调用showOpenFilePicker..."); try { // 注意:headless模式下调用此方法会报错(无UI交互权限),所以用了headless: false await showOpenFilePicker(); } catch (err) { console.log("调用提示(正常现象):", err.message); } }); // await browser.close(); })();
关键细节说明:
- 保存原生函数:一定要先把原生的
showOpenFilePicker存下来,否则直接覆盖后,原有的文件选择功能就完全失效了。 - 异步处理:因为
showOpenFilePicker是异步函数(返回Promise),所以重写的函数必须用async关键字包裹,确保能正确返回原函数的结果。 - 参数传递:用
...args接收所有调用参数,再通过apply(window, args)传递给原生函数,保证原函数能获取到页面传入的配置(比如multiple: true这类参数)。 - 注入时机:
page.evaluateOnNewDocument会在页面所有脚本加载前注入我们的代码,这样页面中任何地方调用showOpenFilePicker都会使用重写后的版本,不会有遗漏。
测试时你会看到控制台先打印自定义的日志,再触发原生的文件选择弹窗(如果是有头模式),完美实现你的需求。
内容的提问来源于stack exchange,提问作者knave123
相关产品推荐
相关产品推荐

