0


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

在这里插入图片描述

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

dom-to-image

或使用

Chrome Headless

,如

Puppeteer

。那如何使用

纯Javascript

解决这种需求呢?

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

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

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

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

完整代码

<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");
        canvas.width = canvas.height =100;const newImg = document.createElement("img");
        newImg.addEventListener("load", onNewImageLoad);
        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");
        body.appendChild(targetImg);functiononNewImageLoad(e){
            ctx.drawImage(e.target,0,0);
            targetImg.src = canvas.toDataURL();}</script></body></html>

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

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

SVG

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

DOM

, SVG图像中的

DOM

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

<input type="file">

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

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

标签: 前端 面试

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

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

还没有评论