0


面试官:请用纯 JS 实现,将 HTML 网页转换为图像

在这里插入图片描述

在工作时,需要实现一个功能:把一个HTML网页的转换为图像。我想到的第一个想法是使用第三方库,但像

  1. dom-to-image

或使用

  1. Chrome Headless

,如

  1. Puppeteer

。那如何使用

  1. Javascript

解决这种需求呢?

让我们尝试在不使用任何库的情况下实现这一点。

使用Canvas将HTML网页转换为图像

由于安全原因,我们不能直接将HTML绘制到Canvas中。我们将采用另一种更安全的方法。

  1. 创建包含渲染内容的SVG图像
  1. <svgxmlns="http://www.w3.org/2000/svg"width="200"height="200"></svg>
  1. 在SVG中插入一个<foreignObject>元素,它将包含HTML
  1. <svgxmlns="http://www.w3.org/2000/svg"width="200"height="200"><foreignObjectwidth="100%"height="100%"></foreignObject></svg>
  1. <foreignObject>节点内添加XHTML内容
  1. <svgxmlns="http://www.w3.org/2000/svg"width="200"height="200"><foreignObjectwidth="100%"height="100%"><divxmlns="http://www.w3.org/1999/xhtml">.
  2. <style>em{color:red;}</style>
  3. Hey there...
  4. </div></foreignObject></svg>
  1. 创建 img 对象,并将 img 的src 属性设置为该图像的data url:
  1. const tempImg = document.createElement('img')
  2. tempImg.src ='data:image/svg+xml,'+encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml">Hey there...</div></foreignObject></svg>')
  1. 将此图像绘制到画布上,并设置画布为img 对象的src属性值:
  1. const newImg = document.createElement('img')
  2. newImg.src ='data:image/svg+xml,'+encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml">Hey there...</div></foreignObject></svg>')// 对图像添加事件监听
  3. newImg.addEventListener('load', onNewImageLoad)// 将图像绘制到画布并设置img.srcfunctiononNewImageLoad(e){
  4. ctx.drawImage(e.target,0,0)
  5. targetImg.src = canvas.toDataURL()}

完整代码

  1. <html><head><metacharset="UTF-8"/><style>body{display: flex;flex-flow: column wrap;align-items: center;justify-content: flex-start;background-image:linear-gradient(0, rgb(169, 144, 177), rgb(205, 169, 223));}h1{margin-top: 5vh;margin-bottom: 1vh;color: white;}p{margin: 0;color: white;}</style></head><body><h1>Convert HTML into Image!<h1/><script>const{ body }= document;const canvas = document.createElement("canvas");const ctx = canvas.getContext("2d");
  2. canvas.width = canvas.height =100;const newImg = document.createElement("img");
  3. newImg.addEventListener("load", onNewImageLoad);
  4. newImg.src ="data:image/svg+xml,"+encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><foreignObject width="100%" height="100%"><div xmlns="http://www.w3.org/1999/xhtml"> Hey there...</div></foreignObject></svg>');const targetImg = document.createElement("img");
  5. body.appendChild(targetImg);functiononNewImageLoad(e){
  6. ctx.drawImage(e.target,0,0);
  7. targetImg.src = canvas.toDataURL();}</script></body></html>

为什么使用SVG和Canvas是安全的?

SVG图像的实现有很大的限制,因为我们不允许

  1. SVG

图像加载外部资源,即使是出现在同一个域上的资源。不允许在SVG图像中编写脚本,无法从其他脚本访问SVG图像的

  1. DOM

, SVG图像中的

  1. DOM

元素不能接收输入事件。因此,无法将特权信息加载到表单控件中(例如

  1. <input type="file">

中的完整路径)并呈现它。

从安全性的角度来看,脚本不能直接接触渲染到画布的DOM节点,这一限制非常重要。

标签: 前端 面试

本文转载自: https://blog.csdn.net/ImagineCode/article/details/124603475
版权归原作者 前端修罗场 所有, 如有侵权,请联系我们删除。

“面试官:请用纯 JS 实现,将 HTML 网页转换为图像”的评论:

还没有评论