我有从 FE 到 Node js BE 的 html 模板。该模板包含带有谷歌地图的 iframe。我需要渲染这个模板,制作屏幕截图并将文件发送回 FE。当我手动打开模板时,模板工作得很好,但是当 puppetear 打开它时(通过 headless: false),我只看到白屏。模板 puppetear 中的所有其他内容均正确呈现。 HTML tempalte 中也有一些变量,我需要用实际值更改它们,但这部分工作得很好,我写它只是为了你们不要与我代码中的变量 parametr 混淆 控制台也有这个错误
Uncaught DOMException: Failed to read the 'sessionStorage' property from 'Window': Access is denied for this document.
HTML 模板示例
<!DOCTYPE html>
<html lang="de">
<head>
<meta http-equiv="Content-Type" content="text/html"/>
<meta charset=UTF-8>
<title>Gabelstapler+map image template</title>
</head>
<style>
.map-trans {
transform: perspective(900px) rotate3d(180,-61,0,22deg);
}
.map-trans iframe {
filter: invert(1) grayscale(1);
-webkit-filter: grayscale(1) invert(1);
}
.stapler-img {
position:absolute;
margin-top: -430px;
margin-left: -150px;
}
</style>
<body>
<div class="container">
<div class="map-trans">
<iframe src="https://www.google.com/maps?hl=de&q=73249&t=k&output=embed" width="100%" height="700" frameborder="0" style="border:0;" allowfullscreen="" aria-hidden="false" tabindex="0"></iframe>
</div>
</div>
</body>
</html>
我写了这样的服务来使用puppetear
我的截图服务
import puppeteer from 'puppeteer';
class ScreenshotService {
constructor() {
this.browser = null;
}
async initialize() {
this.browser = await puppeteer.launch({ headless: false });
}
async takeScreenshot(htmlContent, viewport, extension = 'png') {
const page = await this.browser.newPage();
await page.setViewport(viewport);
await page.setContent(htmlContent, { waitUntil: 'networkidle0' });
await page.waitForSelector('iframe');
await page.waitForSelector('img');
const screenshot = await page.screenshot({ type: extension, fullPage: true });
// await page.close();
return screenshot;
}
async close() {
await this.browser.close();
}
}
export default ScreenshotService;
我如何使用它
async makeScreenshot(template, variables, extension) {
const htmlContent = this.renderHTML(template, variables);
await this.screenshotService.initialize();
const screenshot = await this.screenshotService.takeScreenshot(htmlContent, variables.viewport, extension);
// await this.screenshotService.close();
return screenshot;
}
建议您实际访问 iframe 来拍摄这张照片。您可能需要将其设计为嵌套页面。
async takeScreenshot(htmlContent, viewport, extension = 'png') {
const page = await this.browser.newPage();
await page.setViewport(viewport);
await page.setContent(htmlContent, { waitUntil: 'networkidle0' });
await page.waitForSelector('iframe');
const iframeHandle = await page.$('iframe');
const iframe = iframeElementHandle.contentFrame();
await iframe.evaluate(() => {
//switch this to your screenshot logic
await iframe.screenshot({ path: 'iframe-screenshot.png' });
});
await page.waitForSelector('img');
const screenshot = await page.screenshot({ type: extension, fullPage: true });
// await page.close();
return screenshot;
}