Data URI 还原 SVG:安全解码指南
SVG Data URI 很适合把小图标内联到 HTML 或 CSS 中。但当你接手一段很长的 data:image/svg+xml... 字符串,并想找回原始、可编辑的 SVG 时,它就不那么友好了。
核心思路很简单:去掉 Data URI 头部,解码逗号后的内容,再验证 SVG。更稳妥的做法,是建立一个同时支持 Base64 和 URL 编码的恢复流程,并且不要盲目信任解码后的标记。
本文参考了 Stack Overflow 上关于 Data URI 还原 SVG 的实用讨论:Converting a data URI back to SVG。
先判断 Data URI 类型
常见 SVG Data URI 通常长这样:
data:image/svg+xml;base64,PHN2ZyB4bWxucz0i...
data:image/svg+xml,%3Csvg%20xmlns%3D%22http...
逗号是分界线。逗号前是媒体类型和编码方式,逗号后才是真正的 SVG 内容。
解码 Base64 SVG
如果头部包含 ;base64,先取逗号后的 payload,再做 Base64 解码:
function dataUriBase64ToSvg(dataUri) {
const [, payload] = dataUri.split(",", 2);
if (!payload) {
throw new Error("Invalid SVG Data URI");
}
return new TextDecoder().decode(
Uint8Array.from(atob(payload), (char) => char.charCodeAt(0)),
);
}
这里使用 TextDecoder,避免把 SVG 当成纯 ASCII。真实文件里可能包含中文、符号或设计软件写入的 UTF-8 元数据。
解码 URL 编码 SVG
如果头部没有 ;base64,通常就是 URL 编码:
function dataUriEncodedToSvg(dataUri) {
const [, payload] = dataUri.split(",", 2);
if (!payload) {
throw new Error("Invalid SVG Data URI");
}
return decodeURIComponent(payload);
}
这种格式在 CSS background 中很常见,因为简单图标通常比 Base64 更短,也更容易阅读。
更安全的通用解码函数
生产环境工具最好先识别编码方式,再执行对应解码:
function dataUriToSvg(dataUri) {
const [header, payload] = dataUri.split(",", 2);
if (!header?.startsWith("data:image/svg+xml") || !payload) {
throw new Error("Expected an SVG Data URI");
}
if (header.includes(";base64")) {
return new TextDecoder().decode(
Uint8Array.from(atob(payload), (char) => char.charCodeAt(0)),
);
}
return decodeURIComponent(payload);
}
解码后还要检查结果是否包含 <svg> 根节点,并能被当作 XML 正常解析。这个步骤不要省。
浏览器快速恢复法
临时排查时,可以把 Data URI 粘贴到浏览器地址栏,让浏览器渲染后再保存。但这只适合一次性调试,不适合作为团队流程,因为它不会帮你验证、清理或记录变更。
复用前的最佳实践
- 验证解码后的 XML。
- 移除脚本、事件属性、外部引用和
foreignObject。 - 检查
viewBox、宽高和裁剪区域。 - 提交前用 SVG Viewer 预览。
- 如果还要重新生成 Data URI,用 SVG 转 Data URI 导出。
常见错误
- 解码整段字符串,而不是只解码逗号后的内容。
- 把 URL 编码的 SVG 当成 Base64 解码。
- 没验证 XML 就直接保存和复用。
- 未清理不可信 SVG 内容。
- 忘记 CSS、HTML、JSON 对转义的要求不同。
SVGView 推荐流程
处理重要资源时,建议按这个顺序:
- 解码 Data URI。
- 把 SVG 粘贴到 SVG Viewer。
- 用 SVG Sanitizer 清理风险标记。
- 用 SVG Optimizer 减小体积。
- 用 SVG 转 Data URI 重新导出。
总结
把 Data URI 还原成 SVG,不只是一次解码。它更像一次资源恢复流程:识别编码、只解码 payload、验证 XML、清理风险标记,并在复用前预览最终 SVG。