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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 05:04:08