Data URIをSVGに戻す安全な手順
SVG Data URIは、小さなアイコンをHTMLやCSSへ埋め込むときに便利です。しかし、長いdata:image/svg+xml...文字列だけが残り、編集可能なSVGへ戻したい場合は注意が必要です。
基本は、最初のカンマで分割し、後半のpayloadだけをデコードしてからSVGとして検証することです。この記事はStack Overflowの実用的な議論 Converting a data URI back to SVG を参考にしています。
形式を見分ける
data:image/svg+xml;base64,PHN2ZyB4bWxucz0i...
data:image/svg+xml,%3Csvg%20xmlns%3D%22http...
カンマの前はMIME typeとencoding、後ろが実際のSVG 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を使うと、UTF-8の文字、記号、メタデータをより安全に扱えます。
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として解析できることを確認します。
ベストプラクティス
- 復元したXMLを検証する。
- script、event handler、外部参照、
foreignObjectを取り除く。 viewBox、サイズ、clippingを確認する。- SVG Viewerでプレビューする。
- 必要ならSVG to Data URIで再出力する。
よくある失敗
- Data URI全体をデコードしてしまう。
- URLエンコードされたSVGをBase64として扱う。
- 信頼できないSVGをsanitizeせずに再利用する。
- CSS、HTML、JSONのescaping差を無視する。
SVGViewの流れ
Data URIをデコードし、SVG Viewerに貼り付け、SVG Sanitizerで安全化し、SVG Optimizerで軽量化し、最後にSVG to Data URIで新しい文字列を作成します。