● 6-3. HTML5 Sandbox
HTML5 Sandbox(=サンドボックス)では、iframe(=<iframe>タグ)を使ってページ内に別のページを埋め込んだときに、Cookieの盗難や不用意なポップアップなどをブロックできる。サンドボックスの指定方法は非常に簡単で、次のようにsandbox属性を指定するだけである。
<iframe src="sandboxInner.html" sandbox></iframe>
sandbox属性を指定することによって、(iframeで)サンドボックス化された別のページのコンテンツにおいて、次のアクションが禁止される。
また、sandbox属性に指定する値によって、部分的な許可を設定することもできる。
allow-scripts | サンドボックスのコンテンツにJavaScriptコードの実行を許可する |
---|---|
allow-forms | サンドボックスのコンテンツでフォームのサブミットを許可する |
allow-same-origin | サンドボックスのコンテンツに親フレームと同じポリシーを適用する |
allow-top-navigation | サンドボックスのコンテンツにトップ・ウィンドウのページ遷移を許可する |
ms-allow-popups | サンドボックスのコンテンツにポップアップ・ウィンドウを開くことを許可する |
sandbox属性に指定できる値(部分的な許可を設定できる) |
また、複数の許可を設定したい場合は、以下のようにスペースで区切って複数のオプションをsandbox属性に指定すればよい。
<iframe src="sandboxInner.html" sandbox="allow-scripts ms-allow-popups"></iframe>
このようにsandbox属性を指定することで、プライバシーや予期しない新しいポップアップが開かれるのを避けられるようになり、クロスサイト・スクリプティング(XSS)やSQLインジェクションなどの攻撃を受けたときにも安全に動作するページを作れるようになる。
● 6-4. File Reader API
W3Cでは、ファイルにアクセスするFile APIが草案として公開されているが、IE10 PP2ではこの中からファイルを読み込むFile Reader APIが提供されている。これにより、Webページの中からローカル・ディスク上のファイルを読み込めるようになっている。テキスト・ファイルと画像ファイルを読み込んで、ページ内に表示するサンプルを作成したので、これを基に解説していく。
次のサンプルでは、ファイル入力フィールドを一つ用意してあり、HTMLファイルか画像ファイル(PNG/JPG/GIF)を選択すると、ページ内にその内容を表示する。
それでは、これを実現しているHTML/JavaScriptコードを確認していこう。
<!DOCTYPE html>
<html>
<head>
<script>
function startRead(file) {
var targetFile = file.files[0];
if (targetFile) {
var ext = targetFile.name.substr(targetFile.name.lastIndexOf('.') + 1);
ext = ext.toLowerCase();
switch (ext) {
case "html":
loadHtml(targetFile);
break;
case "jpg":
case "gif":
case "png":
loadImage(targetFile);
break;
}
}
}
function loadHtml(targetFile) {
var reader = new FileReader();
reader.onloadend = function(e) {
document.getElementById("content").innerHTML = reader.result;
};
reader.readAsText(targetFile, "UTF-8");
}
function loadImage(targetFile) {
var reader = new FileReader();
reader.imagediv = document.getElementById('content');
reader.onloadend = function(e) {
var image = document.getElementById('image');
image.src = this.result;
image.style.display="";
}
reader.readAsDataURL(targetFile);
}
</script>
</head>
<body>
<input id="file" name="file" type="file" accept="*/*" onchange="startRead(this)">
<div id="content" style="overflow: auto;"><img src="" id="image" style="display:none"></div>
</body>
</html>
HTMLコードでは、ファイル入力フィールドのonchangeイベントでstartRead関数を呼び出すようになっている。startRead関数内では、拡張子でファイルの種類を判断して、HTMLファイルのときにはloadHtml関数を、画像のときにはloadImage関数をそれぞれ呼び出している。どちらの関数でもFileReaderクラスを使ってファイルを読み込んで、「content」というIDの<div>要素のソースにその読み込み内容を指定している。
上記のコードの例では、ファイル入力フィールドで実現したが、ドラッグ&ドロップでも同様のことが実現できる。このようにローカルのファイルを読めるようになることで、HTMLコードだけで実現可能なアプリケーションの可能性が広がることになる。例えば「Officeファイルを読み込んで編集する」といったアプリケーションも、HTMLコードだけで実現できるかもしれない。
また、HTML5で作成されたゲームのデータを読み込んで、「前回セーブしたところから再開する」といったことも実現できるだろう。例えば、OS(Windows 8)で特定の拡張子とWebアプリケーションの関連付けが行えるようになったら、デスクトップ・アプリケーションとの差はほとんど無くなるだろう。前編では、「将来的に実装が進めば」と前置きして、デスクトップとの統合を予想したが、実現される日は思いのほか近いのかもしれない。
● 6-5. HTML5 Async Scripts
「Async Script」と聞いてワクワクした方。非同期処理がしたいなら、次の節「● 6-6」で紹介するWeb Workersを参照してほしい。HTML5 Async Scriptsは、非同期処理を実現するものではなく、JavaScriptなどのスクリプト・ファイルを非同期に読み込む機能である。
これまでは、JavaScriptファイルの読み込みでページの描画が遅くなることがあった。HTML5 Async Scriptsを使うと、ページの描画とは別に、非同期でスクリプト・ファイルを読み込んで、実行可能になった時点でそのスクリプトを実行する。
それでは、Test Driveのデモを使って説明していこう。
async属性が付いていない左側では、スクリプト・ファイルが読み込まれるまで、画像の表示が待たされている。一方、右側はasync属性が指定されているため、Scriptファイルが読み込まれる前に画像が表示されている。async属性は、以下のように書けばよい。
<script src='Slow.js' async></script>
同じページにあるもう一つのデモも見ていこう。
このデモでは、HTML5 Async Scriptsでスクリプトが非同期に実行されているため、HTML5のロゴ画像が順番に表示されていないことを示している。このようにasync属性を付与した場合は、実行順序がばらばらになるため、スクリプト・ファイル間で依存関係がある場合には使用できない。
● 6-6. Web Workers & Channel Messaging
Web Workersは、UIをブロックすることなく、バックグラウンドでスクリプトを実行できる機能である。バックグラウンドなので、UIを操作するような処理を行えないため、DocumentやWindowなどのオブジェクトにはアクセスできない。
HTML5アプリケーションでは、JavaScriptコードを使ってクライアントサイドで行う処理も多くなることが予想される。そのため、マルチコアのCPUを効率的に使用できるWeb Workersは、重要な機能になってくる。Web WorkersとのやりとりはChannel Messagingを使って行われるので、併せて説明する。
Web Workersを使ったデモとしては、ラスベガスにあるベラジーオの噴水のアニメーションが公開されている(次の画面を参照)。
先ほど、「Web Workersでは、UIを操作できない」と説明したが、このデモでは、Web Workerで座標計算や色の計算を行っている。
それでは、これを実現しているWeb Workersをシンプルなサンプル・コードで説明していこう。
<!DOCTYPE html>
<html>
<head>
<title>Web Workers</title>
</head>
<body>
<div id='sosu'>計算中...</div>
<script>
var worker = new Worker('Worker.js');
worker.onmessage = function(event) {
document.getElementById('sosu').textContent = event.data;
};
worker.postMessage(10000);
</script>
</body>
</html>
Workerクラスのコンストラクタで、「worker.js」ファイルへのURLをパラメータに渡してインスタンス化している。onmessageイベントには、Workerクラス側の処理が完了したときに実行する処理を記述できる。WorkerクラスのpostMessageメソッドを呼び出すことで、Worker側の処理を呼び出せる。postMessageメソッドには、ここでは数値を渡しているが、オブジェクトを渡すこともできる。次にWorker.jsファイルの内容を確認していこう。
onmessage = function(event) {
var maxValue = event.data;
var sosu = [];
for (var num = 2; num < maxValue; num++) {
var isSosu = true;
for (var num2 = 2; num2 < num - 1; num2++) {
if (num % num2 == 0) {
isSosu = false;
break;
}
}
if (isSosu) {
sosu.push(num);
}
}
postMessage(sosu);
}
Worker.jsファイルの中では、onmessageイベントでメッセージを受け取り、最後にpostMessageメソッドで呼び出し元にメッセージを返すという構造になっている。メソッドの引数であるeventのevent.dataプロパティで、呼び出し元から渡された値を取り出せる。ここでは、素数計算を行い、最後に素数のリストをpostMessageメソッドで呼び出し元に返すようにしてある。呼び出し元では、先ほど確認したonmessageイベント・ハンドラで結果を受け取り、素数をページ上に表示している。
このようにpostMessageメソッドとonmessageイベントでやりとりをしている部分は、「HTML5 Channel Messaging」と呼ばれる通信手法である。これは、Web Workerとの通信だけでなく、ウィンドウ間など、ドキュメント間の双方向通信にも使うことができる。
ほかのプログラミング言語で記述すると面倒なスレッド処理も、HTML5なら比較的簡単に書けることがご理解いただけたのではないだろうか。
今回はここまでとする。次回後編では、IE10 PP2のCSS3機能や、ECMAScript 5 Strict Mode、Webパフォーマンスなどについて説明する。
Copyright© Digital Advantage Corp. All Rights Reserved.