gpt4 book ai didi

node.js - 为什么我不能使用 Puppeteer 在 exposeFunction() 函数中访问 'window'?

转载 作者:搜寻专家 更新时间:2023-10-31 22:38:58 30 4
gpt4 key购买 nike

我有一个非常简单的 Puppeteer使用 exposeFunction() 的脚本在 headless 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

指的是注入(inject)函数。如何在 headless Chrome 中访问 window

我知道我可以用 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 传递动态脚本

(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();
})()

addScriptTagreadFileSync

您可以将该函数保存到一个单独的文件中,并使用 addScriptTag 来使用该函数。

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

或使用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;
};

也可以完美地使用 promises,

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

关于node.js - 为什么我不能使用 Puppeteer 在 exposeFunction() 函数中访问 'window'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48281130/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com