【问题标题】:puppeteer page.evaluate cannot exposeFunction with argspuppeteer page.evaluate 无法使用 args 公开函数
【发布时间】:2020-11-20 23:43:09
【问题描述】:

正如我在文档 (here) 中看到的,我们可以像这样将 js 函数暴露给页面,

function do_many_operations(elem) {
    let rect = elem.getBoundingClientRect();
    return rect;
}

async function dummy_fn1(page) {

    // Expose function here
    await page.exposeFunction("do_many_operations", do_many_operations);

    let temp = await page.evaluate(async (a, b) => {
        let elems = document.querySelectorAll("p");
        // Use function here
        let rect = await do_many_operations(elems[0]);
    }, 1, 2);
}

但是,代码中断并显示错误消息,

Error: Evaluation failed: TypeError: elem.getBoundingClientRect is not a function

这意味着 elem arg 到 do_many_operations 不是有效的元素或节点,为什么??

另一个问题是,我们可以将函数注入浏览器上下文吗?这样我们就不必为创建的新页面一次又一次地注入函数。

【问题讨论】:

  • 顺便说一句,addScriptTag 可以很好地解决我上面的问题,但仍然想知道推荐的方法是什么。

标签: javascript puppeteer


【解决方案1】:

调用exposeFunction 注册的函数时有一个序列化过程。 当您调用 do_many_operations(elems[0]); 时,elems[0] 被序列化 (JSON.stringify) 并传递给您在 Node.js 中的函数。在节点方面,该对象没有getBoundingClientRect 函数。 如果你想重用代码,你可以使用evaluate在浏览器端创建函数:

await page.evaluate(() => {
  window.do_many_operations = function(elem) {
    let rect = elem.getBoundingClientRect();
    return rect;
  }
});

【讨论】:

  • 但是在浏览器端创建函数不是我想要的,因为我有很多现有的函数在做这项工作,我只想在我的新项目中重用它们,而不是再次复制和定义它们在代码中。
  • 因此您将无法将元素传递给这些函数。
猜你喜欢
  • 2019-10-20
  • 1970-01-01
  • 2019-09-03
  • 1970-01-01
  • 2020-03-19
  • 2018-02-22
  • 2020-05-09
  • 1970-01-01
  • 2020-03-27
相关资源
最近更新 更多