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

简介: 在工作时,需要实现一个功能:把一个HTML网页的转换为图像。我想到的第一个想法是使用第三方库,但像dom-to-image或使用Chrome Headless,如Puppeteer。那如何使用纯Javascript解决这种需求呢?

在工作时,需要实现一个功能:把一个HTML网页的转换为图像。我想到的第一个想法是使用第三方库,但像dom-to-image或使用Chrome Headless,如Puppeteer。那如何使用纯Javascript解决这种需求呢?

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

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

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

  1. 创建包含渲染内容的SVG图像
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
</svg>
  1. 在SVG中插入一个<foreignObject>元素,它将包含HTML
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
    <foreignObject width="100%" height="100%">
    </foreignObject>
</svg>
  1. <foreignObject>节点内添加XHTML内容
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
    <foreignObject width="100%" height="100%">
        <div xmlns="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.src
function onNewImageLoad(e){
  ctx.drawImage(e.target, 0, 0)
  targetImg.src = canvas.toDataURL()
}

完整代码

<html>
<head>
    <meta charset="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);

        function onNewImageLoad(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节点,这一限制非常重要。

相关文章
|
8月前
|
移动开发 前端开发 JavaScript
征信报告修改器,征信报告生成器,制作软件无痕修改软件【js+html+css】
本项目为信用评分模拟器教学工具,采用HTML5实现,仅供学习参考。核心功能通过JavaScript构建,包含虚拟数据生成、权重分配及信用因素分析(如还款记录、信用使用率等)。
|
8月前
|
前端开发 JavaScript
个人征信电子版无痕修改, 个人信用报告pdf修改,js+html+css即可实现【仅供学习用途】
本代码展示了一个信用知识学习系统的前端实现,包含评分计算、因素分析和建议生成功能。所有数据均为模拟生成
|
6月前
|
编解码 JavaScript 前端开发
如何在网页播放英文的m3u8文件(基于Javascript搭建的在线网页工具)
什么是m3u8?又该如何在网页中高效、便捷地播放英文的m3u8文件呢?今天这篇文章就带你一起了解,并推荐一种基于Javascript搭建的在线网页工具,让你轻松解决播放问题。
1382 0
|
8月前
|
存储 前端开发 JavaScript
仿真银行app下载安装, 银行卡虚拟余额制作app,用html+css+js实现逼真娱乐工具
这是一个简单的银行账户模拟器项目,用于学习前端开发基础。用户可进行存款、取款操作,所有数据存储于浏览器内存中
|
8月前
|
前端开发 容器
处方单图片生成器, 处方单在线制作免费,js+css+html恶搞神器
这是一个电子处方模拟生成系统,使用html2canvas库实现图片导出功能。系统生成的处方单包含多重防伪标识,并明确标注为模拟数据,仅供学习
|
8月前
|
前端开发
个人征信PDF无痕修改软件,个人征信模板可编辑,个人征信报告p图神器【js+html+css仅供学习用途】
这是一款信用知识学习系统,旨在帮助用户了解征信基本概念、信用评分计算原理及信用行为影响。系统通过模拟数据生成信用报告,涵盖还款记录
|
8月前
|
前端开发 JavaScript 容器
制作b超单生成器, 假怀孕b超单图片制作, p图医院证明【css+html+js装逼恶搞神器】
本资源提供一个适合用于熟人之间恶搞的工具,效果逼真,仅供学习参考与娱乐。包含前端技术学习要点:语义化布局、响应式设计、Flexbox、图片自适应
|
8月前
|
前端开发
医院检查单子p图软件,在线制作仿真病历,js+css+html装逼神器
本示例展示如何用HTML/CSS创建医疗信息页面,内容仅供学习参考。页面模拟“阳光医院体检中心”场景,提供预约功能验证(如姓名、手机号、日期)。所有数据仅用于演示
|
Web App开发 JavaScript 前端开发