我想注入一些HTML到一个特定的元素使用的木偶在页面上。
在执行任何JavaScript之前的HTML必须注射。
有两种方法,我想我可以这样做:
page.evaluateOnNewDocument
HTML注入此功能是"is invoked after the document was created"但我不能从它访问DOM元素。例如:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
page.on('console', consoleObj => console.log(consoleObj.text()));
await page.evaluateOnNewDocument(
() => {
const content = document.querySelector('html');
console.log(content);
}
);
await page.goto(process.argv[2]);
await browser.close();
})();
当我访问一个页面这个脚本只是输出换行符。
page.setJavaScriptEnabled
防止的JavaScript之前,我注入HTML执行。作为per the docs虽然,这不会启动执行JavaScript我重新打开它后。例如:我的脚本看起来是这样的:
const fs = require('fs');
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
const html = fs.readFileSync('./example.html', 'utf8');
await page.setJavaScriptEnabled(false)
await page.goto(process.argv[2]);
await page.evaluate(
content => {
const pageEl = document.querySelector('div.page');
let node = document.createElement('div');
node.innerHTML = content;
pageEl.appendChild(node);
}, html
);
await page.setJavaScriptEnabled(true)
await browser.close();
})();
另外,它也有可能做这样的事情this,虽然这似乎对于什么是一个相当简单的要求过于复杂。
是否有更简单的方法来做到这一点,我可以俯瞰?
干杯
看来,这其实是一个非常受欢迎的请求,我或许应该张贴我的问题之前已经搜索更彻底。
不过,我决定对aslushnikov here提出的解决方案。
下面的代码正是我所生产的,以验证这一想法,我敢肯定有改进的余地显著。
我做了一个简单的函数来执行XHR时:
const requestPage = async (url) => {
return new Promise(function (resolve, reject) {
let xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.setRequestHeader('Ignore-Intercept', 'Value');
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
const response = {};
xhr.getAllResponseHeaders()
.trim()
.split(/[\r\n]+/)
.map(value => value.split(/: /))
.forEach(keyValue => {
response[keyValue[0].trim()] = keyValue[1].trim();
});
resolve({ ...response, body: xhr.response });
} else {
reject({
status: this.status,
statusText: xhr.statusText
});
}
};
xhr.onerror = function () {
reject({
status: this.status,
statusText: xhr.statusText
});
};
xhr.send();
});
};
然后我揭露了这个功能的页面。
然后我用这个功能来代替执行允许请求继续下去的XHR并使用该结果作为响应该请求。
await page.setRequestInterception(true);
page.on('request', async (request) => {
if (
request.url() === url
&& (
typeof request.headers()['access-control-request-headers'] === 'undefined'
|| !request.headers()['access-control-request-headers'].match(/ignore-intercept/gi)
) && typeof request.headers()['ignore-intercept'] === 'undefined'
) {
const response = await page.evaluate(`requestPage('${url}')`);
response.body += "hello";
request.respond(response);
} else {
request.continue();
}
});
await page.goto(`data:text/html,<iframe style='width:100%; height:100%' src=${url}></iframe>`);
烦人,它似乎没有可以使用page.evaluate
除非所需的页面在iframe。 (因此await page.goto(`data:text/html....