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>要素と、onloadやonclickのようなonで始まる属性hrefやxlink:hrefの中のjavascript:- 任意の HTML を入れられる
<foreignObject> - トラッキングに使われうる、
http://やhttps://のアドレスを指すhrefの値 - 一部のサーバー側 XML パーサーが危険な形で展開する
<!ENTITY宣言
Base64 にすると、こうしたものはざっと見ただけでは分からなくなります。悪意のある SVG がエンコードされた形で届くことが多いのはそのためです。Base64 自体は何も保護しません。エンコードと暗号化の違い を参照してください。
SVG の判別方法
ほとんどの SVG ファイルは <svg か XML 宣言で始まるので、その Base64 は PHN2Zy か PD94bWwg で始まります。先頭に UTF-8 のバイトオーダーマークがあると、77u/PHN2Zy... のように 77u/ が付きます。
ツールは、XML 宣言、コメント、<!DOCTYPE svg ...> の行を読み飛ばした後、最初の要素が <svg タグであれば SVG として扱います。これらはすべて先頭 2 KB 以内にある必要があります。image/svg+xml を宣言している data URI では、いずれにしても宣言された形式が使われます。HTML ページなどほかのものに埋め込まれた SVG や、非常に長いコメントでタグが 2 KB より後ろにずれた SVG では、「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 以外のテキストが壊れます。UTF-8 を正しくデコードする方法は JavaScript での Base64 で紹介しています。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 エンコード版を作り、サイズを比較できます。