Data URI Scheme について
・ | Data URI Scheme とは? |
・ | Data URI Scheme のフォーマットについて |
・ | ローカルファイルから Data URI Scheme を生成する |
・ | 外部ファイルから Data URI Scheme を生成する |
・ | 任意のバイナリのダウンロードを開始する |
Data URI Scheme とは?
■Data URI Scheme とは?
Data URI Scheme は、URI スキームの一種です。
「コンテンツタイプ」と「バイナリ」の2つの情報を、URI 文字列の中にすべて埋め込む事ができます。
■Data URI Scheme を活用する
URL アドレスを指定可能な場所には、Data URI Scheme を指定する事もできます。
例えば、<IMG> 要素の src プロパティにセットすると、画像として表示することができます。
<img> 要素の src 属性に、Data URI Scheme を指定する
<html>
<body>
<img src="data:image/gif;base64,R0lGODlhIAAgALMAAAAAAMHi9zYA2WZmZre3t/v+/93w/4eHh8zMzP///wAAAAAAAAAAAAAAAAAAAAAAACH5BAEHAAIALAAAAAAgACAAAATVUEgBqq1z3g1y5pgHWh4FGKiRrAl3vAchz6FUpSrrwjPdmTgcqwUYDGA8n+0URA0rRuSrF6oEAs1n0XiUUi3XrG4b9fqsV2yKw+Uiv+jwetMuT88jJipvgedxfBV+ck2FQSsjhIaLiCBXHIYjWmiQhZJjFwiaCBeAAJqZnACNoaAWnqYVpqQWQ41ijbFEF65EsESyF4+jtosVWqy7r768uWBpi8k5wcjKhpMAaWrOe0zQ0tRzTmNLioF6OTUm3oFCRCWd2QYXJUs36uztH98k8u309SURADs=" >
</body>
</html>
■Data URI Scheme の利点
URL アドレスから Data URI Scheme に変更すると、そのファイルの読み込み通信が発生しなくなります。
Data URI Scheme を採用すればするほど、読み込み回数が減り、高速化が期待できます。
■Data URI Scheme の注意点
ファイルサイズが巨大な場合は、採用しないほうがいいでしょう。
Data URI 文字列のサイズは、通常のファイルサイズよりも、必ず大きくなります。(約 4/3 倍)
■対応状況
古いブラウザであるほど、問題や制限があります。
Internet Explorer 8 の場合、CSS や <IMG> などの一部の要素にしか対応していません。
Internet Explorer 8 の場合、文字数に上限(約32KByte)があります。
Internet Explorer 7 以前では、未対応です。
Data URI Scheme のフォーマットについて
■Data URI Scheme のフォーマットについて
■スキームの指定(必須)
まず、『 data: 』と記述します。スキームの指定は必須です。
これで、Data URI Scheme を意味します。
■コンテンツタイプの指定(省略可)
次に データの MIME タイプを指定します。省略可能です。
省略した場合、『 text/plain;charset=US-ASCII 』が採用されます。
■文字セットの指定(省略可)
次に、データの文字セットを指定します。省略可能です。
『 ;charset=文字セット 』と記述します。
■書式の指定(省略可)
次に、データの書式を指定します。省略可能です。
省略した場合、データは、Percent-Encoding となります。
『 ;base64 』と記述した場合、データは、Base64 となります。
■データの指定(必須)
最後に、データを記述します。
カンマ『 , 』を記述して、続けて任意のデータを記述します。
任意の文字列を Percent-Encoding に変換するには、encodeURIComponent() メソッドを使用します。
任意の文字列を Base64 にエンコードする方法については、こちらで解説しています。
■Data URI Scheme の記述例
HTML ファイル(文字コード:US-ASCII、書式:Percent-Encoding)
data:text/html,<html><body>test</body></html>
プレーンテキストファイル(文字コード:UTF-8、書式:Percent-Encoding)
data:text/plain;charset=UTF-8,%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A
プレーンテキストファイル(文字コード:UTF-8、書式:Base64)
data:text/plain;charset=UTF-8;base64,44GC44GE44GG44GI44GK
GIF 画像ファイル(書式:Base64)
data:image/gif;base64,R0lGODlhIAAgALMAAAAAAMHi9zYA2WZmZre3t/v+/93w/4eHh8zMzP///wAAAAAAAAAAAAAAAAAAAAAAACH5BAEHAAIALAAAAAAgACAAAATVUEgBqq1z3g1y5pgHWh4FGKiRrAl3vAchz6FUpSrrwjPdmTgcqwUYDGA8n+0URA0rRuSrF6oEAs1n0XiUUi3XrG4b9fqsV2yKw+Uiv+jwetMuT88jJipvgedxfBV+ck2FQSsjhIaLiCBXHIYjWmiQhZJjFwiaCBeAAJqZnACNoaAWnqYVpqQWQ41ijbFEF65EsESyF4+jtosVWqy7r768uWBpi8k5wcjKhpMAaWrOe0zQ0tRzTmNLioF6OTUm3oFCRCWd2QYXJUs36uztH98k8u309SURADs=
ローカルファイルから Data URI Scheme を生成する
■ローカルファイルから Data URI Scheme を生成する
FileReader クラスは、Safari 5 以前では、未対応です。
FileReader クラスは、Internet Explorer 9 以前では、未対応です。
■取得例
ファイルを読み込み、Data URI Scheme 文字列を得る
<html>
<body>
<form>
<input type="file" id="aaa" >
</form>
<script type="text/javascript">
<!--
// "aaa" という ID 属性のエレメントを取得する
var input_file = document.getElementById("aaa");
// ------------------------------------------------------------
// 値が変化した時に実行されるイベント
// ------------------------------------------------------------
input_file.onchange = function (){
// ファイルが選択されたか
if(!(input_file.value)) return;
// FileReader クラスに対応しているか
if(!(window.FileReader)) return;
// ------------------------------------------------------------
// File オブジェクトを取得(HTML5 世代)
// ------------------------------------------------------------
// ファイルリストを取得
var file_list = input_file.files;
if(!file_list) return;
// 0 番目の File オブジェクトを取得
var file = file_list[0];
if(!file) return;
// ------------------------------------------------------------
// FileReader オブジェクトを生成
// ------------------------------------------------------------
var file_reader = new FileReader();
// ------------------------------------------------------------
// 読み込み成功時に実行されるイベント
// ------------------------------------------------------------
file_reader.onload = function(e){
// 出力テスト
console.log(file_reader.result);
};
// ------------------------------------------------------------
// 読み込みを開始する(Data URI Scheme 文字列を得る)
// ------------------------------------------------------------
file_reader.readAsDataURL(file);
};
//-->
</script>
</body>
</html>
外部ファイルから Data URI Scheme を生成する
■「XMLHttpRequest Level2」 + 「FileReader クラス」を使用する
Cross-Origin 特権付き XMLHttpRequest で利用すると便利です。(拡張機能用の JavaScript など)
Safari 5 では、こちらを使用します。
XMLHttpRequest と FileReader クラスを使って、Data URI Scheme 文字列を得る
// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();
// ------------------------------------------------------------
// XMLHttpRequest の受信が成功した時に実行されるイベント
// ------------------------------------------------------------
xhr.onload = function(){
// ------------------------------------------------------------
// 受信した Blob オブジェクトを取得する
// ------------------------------------------------------------
var blob = xhr.response;
// ------------------------------------------------------------
// FileReader オブジェクトを生成
// ------------------------------------------------------------
var file_reader = new FileReader();
// ------------------------------------------------------------
// 読み込み成功時に実行されるイベント
// ------------------------------------------------------------
file_reader.onload = function(e){
// 出力テスト
console.log(file_reader.result);
};
// ------------------------------------------------------------
// 読み込みを開始する(Data URI Scheme 文字列を得る)
// ------------------------------------------------------------
file_reader.readAsDataURL(blob);
};
// ------------------------------------------------------------
// HTTP メソッドを指定、アクセス先を指定
// ------------------------------------------------------------
xhr.open("GET","https://hakuhin.jp/graphic/title.png");
// ------------------------------------------------------------
// 受信データのタイプを指定
// ------------------------------------------------------------
xhr.responseType = "blob";
// ------------------------------------------------------------
// 送信データを指定し、通信を開始する
// ------------------------------------------------------------
xhr.send(null);
■「XMLHttpRequest Level2」 + 「ArrayBuffer クラス」を使用する
Cross-Origin 特権付き XMLHttpRequest で利用すると便利です。(拡張機能用の JavaScript など)
XMLHttpRequest から、コンテンツタイプを取得するには、レスポンスヘッダを取得します。
レスポンスヘッダを取得する方法については、こちらで解説しています。
XMLHttpRequest と ArrayBuffer クラスを使って、Data URI Scheme 文字列を得る
// ------------------------------------------------------------
// ArrayBuffer から Base64 文字列に変換する関数 (非同期実行)
// ------------------------------------------------------------
function Base64_From_ArrayBuffer_Async(ary_buffer,callback,increment){
var dic = [
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
];
var base64 = "";
var ary_u8 = new Uint8Array( ary_buffer );
var num = ary_u8.length;
var n = 0;
var b = 0;
if(increment === undefined){
increment = 10240;
}
var i = 0;
var j = 0;
function f(){
while(i < num){
b = ary_u8[i];
base64 += dic[(b >> 2)];
n = (b & 0x03) << 4;
i ++;
if(i >= num) break;
b = ary_u8[i];
base64 += dic[n | (b >> 4)];
n = (b & 0x0f) << 2;
i ++;
if(i >= num) break;
b = ary_u8[i];
base64 += dic[n | (b >> 6)];
base64 += dic[(b & 0x3f)];
i ++;
j += 3;
if(j > increment){
j = 0;
setTimeout(f,1);
return;
}
}
var m = num % 3;
if(m){
base64 += dic[n];
}
if(m == 1){
base64 += "==";
}else if(m == 2){
base64 += "=";
}
callback(base64);
}
setTimeout(f,1);
}
// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();
// ------------------------------------------------------------
// XMLHttpRequest の受信が成功した時に実行されるイベント
// ------------------------------------------------------------
xhr.onload = function(){
// ------------------------------------------------------------
// 受信した ArrayBuffer オブジェクトを取得する
// ------------------------------------------------------------
var array_buffer = xhr.response;
// ------------------------------------------------------------
// ArrayBuffer から Base64 文字列に変換する (非同期実行)
// ------------------------------------------------------------
Base64_From_ArrayBuffer_Async(array_buffer,function(base64){
var data_url = "data:" + xhr.getResponseHeader("Content-Type") + ";base64," + base64;
// 出力テスト
console.log(data_url);
});
};
// ------------------------------------------------------------
// HTTP メソッドを指定、アクセス先を指定
// ------------------------------------------------------------
xhr.open("GET","https://hakuhin.jp/graphic/title.png");
// ------------------------------------------------------------
// 受信データのタイプを指定
// ------------------------------------------------------------
xhr.responseType = "arraybuffer";
// ------------------------------------------------------------
// 送信データを指定し、通信を開始する
// ------------------------------------------------------------
xhr.send(null);
■「XMLHttpRequest Level2」 + 「x-user-defined 文字列」を使用する
まず XMLHttpRequest を使って、「x-user-defined 文字列」を取得します。
overrideMimeType() メソッドの引数に、"text/plain; charset=x-user-defined" を指定します。
XMLHttpRequest から、コンテンツタイプを取得するには、レスポンスヘッダを取得します。
レスポンスヘッダを取得する方法については、こちらで解説しています。
XMLHttpRequest と x-user-defined 文字列を使って、Data URI Scheme 文字列を得る
// ------------------------------------------------------------
// x-user-defined 文字列から Base64 文字列に変換する関数 (非同期実行)
// ------------------------------------------------------------
function Base64_From_XUserDefined_Async(x_user_defined,callback,increment){
var dic = [
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
];
var base64 = "";
var num = x_user_defined.length;
var n = 0;
var b = 0;
if(increment === undefined){
increment = 10240;
}
var i = 0;
var j = 0;
function f(){
while(i < num){
b = x_user_defined.charCodeAt(i) & 0xff;
base64 += dic[(b >> 2)];
n = (b & 0x03) << 4;
i ++;
if(i >= num) break;
b = x_user_defined.charCodeAt(i) & 0xff;
base64 += dic[n | (b >> 4)];
n = (b & 0x0f) << 2;
i ++;
if(i >= num) break;
b = x_user_defined.charCodeAt(i) & 0xff;
base64 += dic[n | (b >> 6)];
base64 += dic[(b & 0x3f)];
i ++;
j += 3;
if(j > increment){
j = 0;
setTimeout(f,1);
return;
}
}
var m = num % 3;
if(m){
base64 += dic[n];
}
if(m == 1){
base64 += "==";
}else if(m == 2){
base64 += "=";
}
callback(base64);
}
setTimeout(f,1);
}
// ------------------------------------------------------------
// レスポンスヘッダから Object に変換する関数
// ------------------------------------------------------------
function ResponseHeadersParseObject(str){
var o = new Object();
if(!str) return o;
// 改行コードを統一
var s = str.replace(/\r\n?/g,"\n");
var a = s.split("\n");
var i;
var num = a.length;
for(i=0;i < num;i++){
var m = a[i].match(new RegExp("^(.*):[ ](.*)$","i"));
if(m){
o[m[1]] = m[2];
}
}
return o;
}
if(1){
// ------------------------------------------------------------
// XMLHttpRequest オブジェクトを作成する
// ------------------------------------------------------------
var xhr = new XMLHttpRequest();
// ------------------------------------------------------------
// XMLHttpRequest の受信が成功した時に実行されるイベント
// ------------------------------------------------------------
xhr.onload = function(){
// ------------------------------------------------------------
// 受信した x-user-defined 文字列を取得する
// ------------------------------------------------------------
var binary = xhr.responseText;
// ------------------------------------------------------------
// x-user-defined 文字列 から Base64 文字列に変換する (非同期実行)
// ------------------------------------------------------------
Base64_From_XUserDefined_Async(binary,function(base64){
var data_url = "data:" + xhr.getResponseHeader("Content-Type") + ";base64," + base64;
// 出力テスト
console.log(data_url);
});
};
// ------------------------------------------------------------
// HTTP メソッドを指定、アクセス先を指定
// ------------------------------------------------------------
xhr.open("GET","https://hakuhin.jp/graphic/title.png");
// ------------------------------------------------------------
// コンテンツタイプのオーバーライド設定
// ------------------------------------------------------------
xhr.overrideMimeType("text/plain; charset=x-user-defined");
// ------------------------------------------------------------
// 送信データを指定し、通信を開始する
// ------------------------------------------------------------
xhr.send(null);
}else{
// ------------------------------------------------------------
// GM_xmlhttpRequest 関数を使用する(Greasemonkey スクリプトの場合)
// ------------------------------------------------------------
GM_xmlhttpRequest({
method: "GET",
url: "https://hakuhin.jp/graphic/title.png",
overrideMimeType: "text/plain; charset=x-user-defined",
onload: function (r){
// ------------------------------------------------------------
// レスポンスヘッダ文字列をオブジェクトに変換
// ------------------------------------------------------------
var headers = ResponseHeadersParseObject(r.responseHeaders);
// ------------------------------------------------------------
// 受信した x-user-defined 文字列を取得する
// ------------------------------------------------------------
var binary = r.responseText;
// ------------------------------------------------------------
// x-user-defined 文字列 から Base64 文字列に変換する (非同期実行)
// ------------------------------------------------------------
Base64_From_XUserDefined_Async(binary,function(base64){
var data_url = "data:" + headers["Content-Type"] + ";base64," + base64;
// 出力テスト
console.log(data_url);
});
}
});
}
任意のバイナリのダウンロードを開始する
■任意のバイナリのダウンロードを開始する
アンカーの download プロパティについては、こちらで解説しています。
■動作方法
まず、document.createElement() メソッドを使って、HTMLAnchorElement オブジェクトを作成します。
引数に、"a" を指定します。
href プロパティに、Data URI Scheme 形式で、ダウンロードするファイルを指定します。
download プロパティに、デフォルトのファイル名を指定します。
HTMLAnchorElement オブジェクトを、任意のノードリストに登録します。
最後に、click() メソッドを実行します。
■動作例
任意の Blob オブジェクトのダウンロードを開始する
// ------------------------------------------------------------
// Blob オブジェクトを作成(UTF-8 形式のプレーンテキスト)
// ------------------------------------------------------------
var blob = new Blob(["保存テスト"] , {type:"text/plain"});
// ------------------------------------------------------------
// FileReader オブジェクトを生成
// ------------------------------------------------------------
var file_reader = new FileReader();
// ------------------------------------------------------------
// 読み込み成功時に実行されるイベント
// ------------------------------------------------------------
file_reader.onload = function(e){
// ------------------------------------------------------------
// HTMLAnchorElement オブジェクトを作成する
// ------------------------------------------------------------
var anchor = document.createElement("a");
// ターゲットを設定
anchor.target = "_blank";
// ダウンロードするファイルを Data URI Scheme 文字列で指定
anchor.href = file_reader.result;
// デフォルトのファイル名を指定
anchor.download = "mystring.txt";
// ------------------------------------------------------------
// ダウンロードを開始する
// ------------------------------------------------------------
document.body.appendChild(anchor);
anchor.click();
anchor.parentNode.removeChild(anchor);
};
// ------------------------------------------------------------
// 読み込みを開始する(Data URI Scheme 文字列を得る)
// ------------------------------------------------------------
file_reader.readAsDataURL(blob);
任意の ArrayBuffer オブジェクトのダウンロードを開始する
// ------------------------------------------------------------
// ArrayBuffer から Base64 文字列に変換する関数 (非同期実行)
// ------------------------------------------------------------
function Base64_From_ArrayBuffer_Async(ary_buffer,callback,increment){
var dic = [
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
];
var base64 = "";
var ary_u8 = new Uint8Array( ary_buffer );
var num = ary_u8.length;
var n = 0;
var b = 0;
if(increment === undefined){
increment = 10240;
}
var i = 0;
var j = 0;
function f(){
while(i < num){
b = ary_u8[i];
base64 += dic[(b >> 2)];
n = (b & 0x03) << 4;
i ++;
if(i >= num) break;
b = ary_u8[i];
base64 += dic[n | (b >> 4)];
n = (b & 0x0f) << 2;
i ++;
if(i >= num) break;
b = ary_u8[i];
base64 += dic[n | (b >> 6)];
base64 += dic[(b & 0x3f)];
i ++;
j += 3;
if(j > increment){
j = 0;
setTimeout(f,1);
return;
}
}
var m = num % 3;
if(m){
base64 += dic[n];
}
if(m == 1){
base64 += "==";
}else if(m == 2){
base64 += "=";
}
callback(base64);
}
setTimeout(f,1);
}
// ------------------------------------------------------------
// コンテンツタイプ
// ------------------------------------------------------------
var content_type = "text/plain";
// ------------------------------------------------------------
// ArrayBuffer オブジェクトを作成
// ------------------------------------------------------------
// Uint8Array オブジェクトを作成
var ary_u8 = new Uint8Array([0xe4,0xbf,0x9d , 0xe5,0xad,0x98 , 0xe3,0x83,0x86 , 0xe3,0x82,0xb9 , 0xe3,0x83,0x88]);
// ArrayBuffer オブジェクトを取得
var array_buffer = ary_u8.buffer;
// ------------------------------------------------------------
// ArrayBuffer から Base64 文字列に変換する (非同期実行)
// ------------------------------------------------------------
Base64_From_ArrayBuffer_Async(array_buffer,function(base64){
// ------------------------------------------------------------
// HTMLAnchorElement オブジェクトを作成する
// ------------------------------------------------------------
var anchor = document.createElement("a");
// ターゲットを設定
anchor.target = "_blank";
// ダウンロードするファイルを Data URI Scheme 文字列で指定
anchor.href = "data:" + content_type + ";base64," + base64;
// デフォルトのファイル名を指定
anchor.download = "mystring.txt";
// ------------------------------------------------------------
// ダウンロードを開始する
// ------------------------------------------------------------
document.body.appendChild(anchor);
anchor.click();
anchor.parentNode.removeChild(anchor);
});