如何将 Base64 解码为 SVG
- 粘贴 Base64、
data:image/svg+xml;base64,...URI,或者包含它的 CSS 或 HTML。URL 编码的 SVG data URI(data:image/svg+xml,%3Csvg...)同样可以。 - 预览会绘制图形并列出其尺寸,如果浏览器报告没有固定尺寸,则显示“可缩放”。下方是完整的 XML 源码。
- 点击 下载文件 保存
.svg,或在源码区域选中标记进行复制。
SVG 是纯文本,所以解码后得到的是可读的标记。除了保存文件,你还可以弄清样式表中的某个图标到底画了什么、用了哪些颜色,或者为什么无法渲染。
SVG 的安全性:图片预览与内联标记
SVG 文件是一个文档。它可以包含 <script> 元素、onload 之类的事件属性、链接、通过 <foreignObject> 嵌入的 HTML,以及对外部图片和字体的引用。浏览器如何处理这些内容,取决于 SVG 的加载方式:
| SVG 的使用方式 | 运行脚本 | 加载外部资源 |
|---|---|---|
<img src="...">、CSS background-image、本页的预览 | 否 | 否 |
HTML 中的内联 <svg>,或通过 innerHTML 插入 | 是 | 是 |
在标签页中直接打开,或放在 <object>、<embed>、<iframe> 中 | 是 | 是 |
本页解码字节后,以 data:image/svg+xml;base64,... 的形式交给 <img>,所以无论文件包含什么,都只会被绘制出来。源码区域只显示文本,不做任何解释执行。
如果你打算把 SVG 内联到页面中,请先阅读源码,留意以下内容:
<script>元素以及以on开头的属性,例如onload或onclickhref或xlink:href中的javascript:<foreignObject>,它可以携带任意 HTML- 指向
http://或https://地址的href值,可能被用于跟踪 <!ENTITY声明,某些服务端 XML 解析器会以危险的方式展开它们
Base64 让人一眼看不出这些内容,所以恶意 SVG 常常以编码形式出现。Base64 本身不提供任何保护;见 编码与加密。
如何识别 SVG
大多数 SVG 文件以 <svg 或 XML 声明开头,所以它们的 Base64 以 PHN2Zy 或 PD94bWwg 开头。前面加上 UTF-8 字节顺序标记会多出 77u/,例如 77u/PHN2Zy...。
在跳过 XML 声明、注释和 <!DOCTYPE svg ...> 行之后,如果 <svg 标签是第一个元素,并且这一切都在前 2 KB 之内,工具就会把数据当作 SVG。如果 data URI 声明了 image/svg+xml,则无论如何都采用声明的类型。如果 SVG 嵌在其他内容中,比如 HTML 页面,或者一段很长的注释把标签推到了 2 KB 之后,你会看到“这看起来不像 SVG”的提示;在 MIME 类型 中填入 image/svg+xml 即可渲染。
SVG 无法渲染时
- “无法渲染此 SVG”。 XML 格式有误:有未闭合的标签、未转义的
&,或者字符串被截断,缺少结尾的</svg>。先看看源码的末尾。 - 在这里能渲染,在你的网站上却不行。 检查网站是如何提供这个文件的。使用 data URI 时,类型必须是
image/svg+xml;以text/plain或application/octet-stream提供的文件同样无法作为图片渲染。 - 内联时能渲染,作为 data URI 却不行。 根元素缺少
xmlns="http://www.w3.org/2000/svg"。HTML 中的内联 SVG 不需要它,图片则需要。 - 颜色不对。 作为图片使用的 SVG 无法继承页面的
currentColor或 CSS。它只会按文件中定义的颜色绘制,默认是黑色。
在代码中使用解码后的 SVG
在浏览器中,显示 Base64 SVG 的安全做法是让它保持为图片:
const img = new Image();
img.src = "data:image/svg+xml;base64," + b64;
document.body.append(img);
如果改写成 element.innerHTML = atob(b64),标记就会进入你的页面,其中的脚本和事件处理程序会以你页面的权限运行。另外请注意,atob() 会把字节作为 Latin-1 字符返回,这会破坏 SVG 中的非 ASCII 文本;JavaScript 中的 Base64 介绍了如何正确解码 UTF-8。要编码 SVG,请使用 SVG 转 Base64。
常见问题
打开来源不明的 SVG 安全吗?
以图片形式打开是安全的:通过 <img> 或 CSS 显示 SVG 时,浏览器不会运行脚本,也不会加载外部文件,本页就是这样预览的。如果在标签页中直接打开,或者内联粘贴到 HTML 中,同一个文件就可以运行 JavaScript,所以请先阅读源码。
为什么页面说我的 SVG 看起来像文本?
跳过 XML 声明、注释和 <!DOCTYPE> 之后,文本不是以 <svg> 标签开头,例如它被包在 HTML 中。在 MIME 类型 中填入 image/svg+xml,预览就会切换到 SVG 渲染。
以 H4sI 开头的 Base64 字符串在这里是什么意思?
这是 gzip 压缩的数据,通常是 .svgz 文件。页面会指出这一点;点击 再次解码 即可解压,得到普通的 SVG 标记。
能编辑 SVG 后再转回 Base64 吗?
从源码区域复制标记,编辑后粘贴到 SVG 转 Data URI,它会生成 Base64 和 URL 编码两个版本,并比较它们的大小。