为什么我无法使用 Puppeteer 访问 hideFunction() 函数中的“窗口”?

2024-03-13

我有一个非常简单的傀儡师 https://github.com/GoogleChrome/puppeteer使用的脚本exposeFunction() https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pageevaluatepagefunction-args在无头 Chrome 中运行一些东西。

(async function(){

    var log = console.log.bind(console),
        puppeteer = require('puppeteer');


    const browser = await puppeteer.launch();
    const page = await browser.newPage();

    var functionToInject = function(){
        return window.navigator.appName;
    }

    await page.exposeFunction('functionToInject', functionToInject);

    var data = await page.evaluate(async function(){
        console.log('woo I run inside a browser')
        return await functionToInject();
    });

    console.log(data);

    await browser.close();

})()

这失败了:

ReferenceError: window is not defined

这是指注入的函数。我怎样才能访问window在无头 Chrome 中?

我知道我能做到evaluate()相反,但这不适用于我动态传递的函数:

(async function(){

    var log = console.log.bind(console),
        puppeteer = require('puppeteer');

    const browser = await puppeteer.launch();
    const page = await browser.newPage();

    var data = await page.evaluate(async function(){
        console.log('woo I run inside a browser')
        return window.navigator.appName;
    });

    console.log(data);

    await browser.close();

})()

evaluate功能

您可以通过动态脚本 using evaluate.

(async function(){
    var puppeteer = require('puppeteer');
    const browser = await puppeteer.launch();
    const page = await browser.newPage();

    var functionToInject = function(){
        return window.navigator.appName;
    }

    var data = await page.evaluate(functionToInject); // <-- Just pass the function
    console.log(data); // outputs: Netscape
    
    await browser.close();
})()

addScriptTag and readFileSync

您可以将该函数保存到单独的文件中并使用该函数addScriptTag.

await page.addScriptTag({path: 'my-script.js'});

or evaluate with readFileSync.

await page.evaluate(fs.readFileSync(filePath, 'utf8'));

或者,将参数化函数作为字符串传递给page.evaluate.

await page.evaluate(new Function('foo', 'console.log(foo);'), {foo: 'bar'});

动态创建一个新函数

怎么样把它变成一个runnable功能:D?

function runnable(fn) {
  return new Function("arguments", `return ${fn.toString()}(arguments)`);
}

上面将使用提供的参数创建一个新函数。我们可以传递任何我们想要的函数。

比如下面的函数window,连同参数,

function functionToInject() {
  return window.location.href;
};

也能完美地履行诺言,

function functionToInject() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(window.location.href);
    }, 5000);
  });
}

并有论据,

async function functionToInject(someargs) {
  return someargs; // {bar: 'foo'}
};

调用所需的函数evaluate,

var data = await page.evaluate(runnable(functionToInject), {bar: "foo"});
console.log(data); // shows the location
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么我无法使用 Puppeteer 访问 hideFunction() 函数中的“窗口”? 的相关文章

随机推荐