特集
» 2011年07月29日 00時00分 公開

特集:IE10(プレビュー版)概説(中編):Internet Explorer 10 PP2のHTML5機能 (2/2)

[尾崎義尚,著]
前のページへ 1|2       

6-3. HTML5 Sandbox

 HTML5 Sandbox(=サンドボックス)では、iframe(=<iframe>タグ)を使ってページ内に別のページを埋め込んだときに、Cookieの盗難や不用意なポップアップなどをブロックできる。サンドボックスの指定方法は非常に簡単で、次のようにsandbox属性を指定するだけである。

<iframe src="sandboxInner.html" sandbox></iframe>

iframeにHTML5 Sandboxを指定したサンプル・コード
iframeにsandbox属性を指定するだけで、内部コンテンツをSandboxに閉じ込めることができる。

 sandbox属性を指定することによって、(iframeで)サンドボックス化された別のページのコンテンツにおいて、次のアクションが禁止される。

  • ポップアップ・ウィンドウの表示
  • リンクによる新しいウィンドウの表示
  • Cookie、ローカル・ストレージ、ほかのドキュメントのDOM
  • トップ・ウィンドウのナビゲーション
  • フォームのサブミット
  • プラグインのインスタンス化
  • ページのリフレッシュ、入力フィールドへのオート・フォーカス、オーディオやビデオの自動再生
  • HTC(HTML Components)、バイナリ・ビヘイビア、databinding、window.external

 また、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属性に許可する機能を並べることで、部分的に機能を許可することができる。

 このようにsandbox属性を指定することで、プライバシーや予期しない新しいポップアップが開かれるのを避けられるようになり、クロスサイト・スクリプティング(XSS)やSQLインジェクションなどの攻撃を受けたときにも安全に動作するページを作れるようになる。

6-4. File Reader API

 W3Cでは、ファイルにアクセスするFile APIが草案として公開されているが、IE10 PP2ではこの中からファイルを読み込むFile Reader APIが提供されている。これにより、Webページの中からローカル・ディスク上のファイルを読み込めるようになっている。テキスト・ファイルと画像ファイルを読み込んで、ページ内に表示するサンプルを作成したので、これを基に解説していく。

 次のサンプルでは、ファイル入力フィールドを一つ用意してあり、HTMLファイルか画像ファイル(PNG/JPG/GIF)を選択すると、ページ内にその内容を表示する。

[Browse]ボタンをクリックして、HTMLファイルを指定
さらに画像ファイルを指定
ファイルの読み込みサンプル
ファイル入力フィールドで、HTMLファイルを選択すると、その内容が表示される。画像ファイルを選択すると、ページ内に画像が表示される。

 それでは、これを実現している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>

File Reader APIでファイルを読み込むサンプル・コード
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 Scriptsのデモ(1)
読み込みが遅いスクリプト・ファイルによって、ページの描画がブロックされてしまった[Without HTML5 Async](左)に対して、[With HTML5 Async](右)ではasync属性の指定で非同期にスクリプトの読み込みと実行が行われているため、読み込み中でも画像が表示されている。

 async属性が付いていない左側では、スクリプト・ファイルが読み込まれるまで、画像の表示が待たされている。一方、右側はasync属性が指定されているため、Scriptファイルが読み込まれる前に画像が表示されている。async属性は、以下のように書けばよい。

<script src='Slow.js' async></script>

async属性を指定した<script>タグのサンプル・コード
<script>タグの中にasync属性を指定している。

 同じページにあるもう一つのデモも見ていこう。

Async Scriptsのデモ(2)
画像が非同期に読み込まれているため、HTML5のロゴ画像が崩れている。

 このデモでは、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のデモ(上)と、ベラジーオの写真(下)
ベラジーオの噴水を再現したアニメーションを表示するデモが公開されている。

 先ほど、「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>

Web Workersの処理を呼び出すサンプル・コード
Workerクラスをインスタンス化して、postMessageメソッドで呼び出している。結果を受け取るonmessageイベントで、結果をページに表示している。

 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クラスで呼び出される「Worker.js」ファイルの実装内容
onmessageイベントにバックグランドで実行する処理を記述する。引数のevent.dataプロパティで(先ほどのpostMessageメソッドに指定された)数値を受け取り、最後のpostMessageメソッドの呼び出しにより計算結果を返している。

 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パフォーマンスなどについて説明する。

「特集:IE10(プレビュー版)概説」のインデックス

特集:IE10(プレビュー版)概説

前のページへ 1|2       

Copyright© Digital Advantage Corp. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。