Data URI scheme

データURIスキーム（英語: data URI scheme）とは、あたかも外部リソースを読み込むのと同じように、ウェブページにインラインにデータを埋めこむ手段を提供するURIスキームである。ファイルリテラル、あるいはヒアドキュメントの一形態である。この技術を利用することで、通常は別のデータに分かれている画像やスタイルシートなどの要素を、1つのHTTPリクエストによって読み込むことが可能になる。これにより、HTTPリクエスト数が削減され、データの転送効率が改善される可能性がある。また、一部のブラウザ拡張機能でも、画像などのコンテンツを単一のHTMLファイル内にパッケージングしてユーザーに届けるために利用されている。2018年現在[update]、データURIは主要なほとんどのブラウザで完全にサポートされている。ただし、Internet ExplorerとMicrosoft Edgeでは、一部の機能が実装されていない。 フルサポートされたブラウザでは、JavaScriptで生成されたコンテンツであってもwindow.location.hrefに値を設定することで通常の外部ファイルと同様に「ダウンロード」をすることができる。 2018年には、WHATWGのFetch Standardで改めて定義がなされることとなった。 データをテキスト形式で埋め込むのでHTTPリクエストやヘッダのトラフィックが低減できる。データによってはそのまま埋め込むことができないためエンコードのためのオーバーヘッドが起こる（例えば、600バイトのデータをデータURIスキームで埋め込む場合、Base64でエンコードされ約800バイトになり、200バイトほどデータ量は増える）が、それでもトラフィックを軽減できる事の方が有用である。 小さなファイルを多数転送するよりもデータURIスキームを使った方が高速である。TCPのファイル転送にはスロースタートの仕組みが採用されている。小さなファイル1つ1つがTCPコネクションを要求した場合、転送速度はラウンドトリップタイムや帯域幅に応じて制限される。（ただし、HTTP/1.1で規定された持続的接続 (Keep alive)が有効であったり、HTTP/2を使用していたりする場合、この長所は価値が下がる。） HTTPSを使用したウェブページを閲覧する場合、ブラウザはページ内で発生した全てのダウンロードに対してセキュアな接続を要求するか、一部セキュリティで守られていない要素があることをユーザに警告する。サーバーの設定にミスがあった場合、通常のHTTPリクエストに比べてHTTPSのリクエストは大きなオーバーヘッドが発生する。データURIスキームにより全てのファイルを1つにまとめることができればこのような心配はしなくてもよい。 多くのブラウザは1つのドメイン名に対する接続数に限りがある。データURIスキームにより全てのファイルを1つにまとめることができれば接続数の制限は問題にはならない。 外部データへのアクセスが制限されている環境で有用である。 1つのHTMLファイルでマルチメディアを表現することができる。 電子メールで外部ファイルや添付ファイルを使用せずに画像を表示できる。 データURIスキームによってダウンロードされたファイルは個別にキャッシュされない。HTMLやCSSのファイルがダウンロードされるたびにデータもダウンロードされる。 HTMLやCSSのファイルが更新されるたびに、その作者はエンコードや埋め込みをやり直さなければならない。 古いInternet Explorerでサポートされていない。バージョン8ではデータサイズが32kBに制限されている。 Internet Explorerのバージョン8とバージョン9では画像でしか使用できない。JavaScriptで生成されたコンテンツはダウンロードすることができない。データURIスキームではデータは単純な文字列として表現される。ブラウザなど、多くの処理環境ではメタデータ、データ圧縮、コンテントネゴシエーションのような複雑な処理はサポートしないであろう。他にサポートされないであろうと思われる要素に、電子メールクライアントのマルチパート形式やmessage/rfc822などがある。 Base64でエンコードされたデータは元のサイズより1/3程度大きくなる（バイト単位）。ただし、このオーバーヘッドはHTTPサーバーがレスポンスをgzipで圧縮した場合2～3%にまで軽減される。 データURIスキームでダウンロードしたファイルには通常のリンクからダウンロードしたファイルと違ってファイル名がない。保存するときのファイル名はMIMEタイプごとに用意されたデフォルトの物となる。ただし、HTML5ではa要素にダウンロード時のファイル名を指定できるdownload属性が追加されたため、一部のブラウザではこの問題は解決した。 例え1つのウェブページに埋め込むデータであっても、同じデータを複数使用すると使用された数だけコピーが必要となる。外部データの場合はいくつデータを使用する場合でも1つで済む。 データURIスキームはアンチウイルスソフトウェアのフィルタリング処理を難しくする。 データURIの構文は、IETFが1998年に標準プロトコル案RFC 2397として定義され、続いて、URIスキームの構文が定義された。構文は、以下の通りである。 data:[<MIME-type>][;charset=<encoding>][;base64],<data> エンコードが必要なデータに対してはBase64のエンコード形式を指定する。エンコード形式の指定が無い場合、データはURLで使用可能な文字についてはASCIIコードで記述し、それ以外の文字については標準の%xx形式（パーセントエンコーディング）でエンコードする。MIMEタイプが省かれた場合、デフォルト値のtext/plain;charset=US-ASCIIが指定されたものとする。（その場合、charsetだけの指定も可能。） いくつかのブラウザ (Google Chrome, Opera, Safari, Firefox) では;charsetと;base64の順番が逆になっても正常に処理される。Internet Explorerでは;charsetと;base64の順番は逆になってはならない。データサイズはオクテット単位である。 赤い小さな点の画像 () を表示する HTML: <img src="data:image/png;base64,iVBORw0KGgoAAA ANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4 //8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU 5ErkJggg==" alt="Red dot" /> この例はフォーマットのために改行されている。 Data URI も含めた実際の URI では、制御文字 (ASCII 0 から 31 までと 127) とスペース (ASCII 32) は除外文字である。つまり、空白文字が data URI に入っていてはいけない。 しかし、HTML4 と HTML5 においては、要素の属性値 (上記の "src" のような) の中の改行は無視される [要出典]。 したがって、上記の例の data URI は改行が無視されて正常に処理される。 これは HTML の機能であって data URI の機能ではないため、HTML 以外では URI 内の空白文字が無視される挙動は使えないことに留意。 背景に画像を含む CSS ルール: ul.checklist li.complete { padding-left: 20px; background: white url('data:image/png;base64,iVB\ ORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEU\ AAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8\ yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAEl\ FTkSuQmCC') no-repeat scroll left top; } \ + <LF> の行末は、次行に継続することを表す CSS の機能である。これは CSS 解釈時に除去されて、data URI が空白のないように正しく再構築される。 次のスクリプトは埋め込みデータを元にサブウィンドウを表示する。脚注などに使用できる。 window.open('data:text/html;charset=utf-8,' + encodeURIComponent( // URL書式にエスケープ '<!DOCTYPE html>'+ '<html lang="en">'+ '<head><title>Embedded Window</title></head>'+ '<body><h1>42</h1></body>'+ '</html>' ) ); この例をInternet Explorer 8で表示しようとしても実行ファイルのセキュリティ制限のため失敗する。（訳注:en版のwikipediaにあった例をそのまま記述してある。セキュリティについて考慮すべき例なのでInternet Explorer 8以外でも注意。） Base64 エンコードの JPEG 画像を埋め込んだ SVG <svg> <image width="64" height="24" href="data:image/jpeg;base64, /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDADIiJSwlHzIsKSw4NTI7S31RS0VFS5ltc1p9tZ++u7Kf r6zI4f/zyNT/16yv+v/9////////wfD/////////////2wBDATU4OEtCS5NRUZP/zq/O//////// ////////////////////////////////////////////////////////////wAARCAAYAEADAREA AhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAQMAAgQF/8QAJRABAAIBBAEEAgMAAAAAAAAAAQIR AAMSITEEEyJBgTORUWFx/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAA AAD/2gAMAwEAAhEDEQA/AOgM52xQDrjvAV5Xv0vfKUALlTQfeBm0HThMNHXkL0Lw/swN5qgA8yT4 MCS1OEOJV8mBz9Z05yfW8iSx7p4j+jA1aD6Wj7ZMzstsfvAas4UyRHvjrAkC9KhpLMClQntlqFc2 X1gUj4viwVObKrddH9YDoHvuujAEuNV+bLwFS8XxdSr+Cq3Vf+4F5RgQl6ZR2p1eAzU/HX80YBYy JLCuexwJCO2O1bwCRidAfWBSctswbI12GAJT3yiwFR7+MBjGK2g/WAJR3FdF84E2rK5VR0YH/9k="/> </svg> MHTML MIME