我正在使用 Puppeteer适用于 headless Chrome。我希望评估页面内的一个函数,该函数使用其他函数的一部分,在别处动态定义。
下面的代码是一个最小的示例/证明。实际上 functionToInject()
和 otherFunctionToInject()
更复杂并且需要页面 DOM。
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(someURL);
var functionToInject = function(){
return 1+1;
}
var otherFunctionToInject = function(input){
return 6
}
var data = await page.evaluate(function(functionToInject, otherFunctionToInject){
console.log('woo I run inside a browser')
return functionToInject() + otherFunctionToInject();
});
return data
当我运行代码时,我得到:
Error: Evaluation failed: TypeError: functionToInject is not a function
据我了解:functionToInject
没有被传递到页面的 JS 上下文中。但是如何将它传递到页面的 JS 上下文中呢?
您可以使用 addScriptTag
向页面上下文添加功能:
const browser = await puppeteer.launch();
const page = await browser.newPage();
function functionToInject (){
return 1+1;
}
function otherFunctionToInject(input){
return 6
}
await page.addScriptTag({ content: `${functionToInject} ${otherFunctionToInject}`});
var data = await page.evaluate(function(){
console.log('woo I run inside a browser')
return functionToInject() + otherFunctionToInject();
});
console.log(data);
await browser.close();
这个例子是用字符串连接解决这个问题的肮脏方法。更干净的方法是在 addScriptTag
方法中使用 url
或 path
。
或者使用exposeFunction
(但现在功能被包装在 Promise 中):
const browser = await puppeteer.launch();
const page = await browser.newPage();
var functionToInject = function(){
return 1+1;
}
var otherFunctionToInject = function(input){
return 6
}
await page.exposeFunction('functionToInject', functionToInject);
await page.exposeFunction('otherFunctionToInject', otherFunctionToInject);
var data = await page.evaluate(async function(){
console.log('woo I run inside a browser')
return await functionToInject() + await otherFunctionToInject();
});
console.log(data);
await browser.close();