Web Storage を使ってファイルをローカルに保存する

このトピックは、「ローカル ファイルを読み取る方法」の続きです。ここでは、Web Storage を使ってサイズの小さなファイルをローカルに保存する方法について説明します。

適度なサイズのファイルを (ローカルに) 保存する最も簡単な方法の 1 つは、Web Storage を使う方法です。Web Storage は従来の Cookie と似ていますが、一般的により大きな記憶域割り当てを提供します。たとえば、Internet Explorer 10 では、ドメインあたり 10 MG を使って、文字列、ファイル、JavaScript オブジェクトなどのさまざまなアイテムをローカルに格納します。この手法を使ってファイルをローカルに保存する方法を次のコード例に示します。

  次のコード例を実行するには、ファイル APIWeb Storage をサポートするブラウザー (たとえば、Internet Explorer 10 以降) が必要です。

Canvas 描画アプリ

以降で紹介するコード例をより現実的にするために、最初の例では、HTML5 の canvas ベースの単純な描画アプリを紹介します。このようなアプリは、ファイルをローカルに保存する正当なニーズを提供します。この例については、アーティストの作品をローカルに保存できるように、拡張を加えていきます。

例 1


<!DOCTYPE html>
<html>
  <head>
    <title>Simple Drawing App</title>
    <meta http-equiv="X-UA-Compatible" content="IE=10">
    <style>
      html { 
       -ms-touch-action: none;
       text-align: center; /* Center all contents of the page. */
      }
    </style>
  </head>
  <body>
    <h1>Simple Drawing App</h1>
    <h3>Example 1</h3>
    <canvas id="drawSurface" width="500" height="500" style="border:1px solid black;"></canvas> <!-- The canvas element can only be manipulated via JavaScript -->
    <div>
      <button id="erase">Erase</button>
    </div>
    <script>
      if (!document.createElement('canvas').getContext) {
        document.querySelector('body').innerHTML = "<h1>Canvas is not supported by this browser.</h1><p>To use this application, upgrade your browser to the latest version.</p>";
      }
      else {
        window.addEventListener('load', init, false); // Safety first.
  
        function init() {
          var canvas = document.getElementById('drawSurface'); // A static variable, due to the fact that one or more local functions access it.
          var context = canvas.getContext('2d'); // A static variable, due to the fact that one or more local functions access it.
  
          context.fillStyle = "purple";
  
          if (window.navigator.msPointerEnabled) {
            canvas.addEventListener('MSPointerMove', paintCanvas, false);
          }
          else {
            canvas.addEventListener('mousemove', paintCanvas, false);
          }
  
          document.getElementById('erase').addEventListener('click', eraseCanvas, false);
  
          function paintCanvas(event) { // The "event" object contains the position of the pointer/mouse.
            context.fillRect(event.offsetX, event.offsetY, 4, 4); // Draw a 4x4 rectangle at the given coordinates (relative to the canvas box). As of this writing, not all browsers support offsetX and offsetY.
          } // paintCanvas
  
          function eraseCanvas() {
            context.clearRect(0, 0, context.canvas.width, context.canvas.height);
          } // eraseCanvas
        } // init      
      } // else
    </script>
  </body>
</html>

この非常に単純なアプリを使うには、マウスを四角形の canvas 領域に移動します。図を削除するには、単に [消去] ボタンをクリックします。

このコードでおそらく最も複雑な側面は、init 内でローカルに宣言されている、canvascontext の 2 つの "静的" 変数です。ローカル関数 (paintCanvaseraseCanvas) はこれらの変数にアクセスするため、init の終了後もこれらにアクセスできます。これには、グローバル名前空間が雑然とするのを防ぐ効果があります。このアプリは、タッチ対応デバイス (タブレットなど) でも動作します。

Web Storage を使ってファイルを保存する

既に説明したように、最新のブラウザー (Windows Internet Explorer 9 以降を含む) では、Web Storage がサポートされています。Web Storage には、ローカル記憶域とセッション記憶域の 2 種類があります。名前が示すように、セッション記憶域は、特定のブラウザー セッションの間だけ保持されます。これに対し、ローカル記憶域は無期限に保持されます。

ここでは、ローカル記憶域を使って、ユーザーの図を保存します。次の例に示すように、これは比較的簡単な操作です。

例 2


<!DOCTYPE html>
<html>
  <head>
    <title>Simple Drawing App</title>
    <meta http-equiv="X-UA-Compatible" content="IE=10">
    <style>
      html { 
       -ms-touch-action: none;
       text-align: center; /* Center all contents of the page. */
      }
    </style>
  </head>
  <body id="bodyElement"> <!-- This ID is used in the following script block for feature detection. -->
    <h1>Simple Drawing App</h1>
    <h3>Example 2</h3>
    <canvas id="drawSurface" width="500" height="500" style="border:1px solid black;"></canvas> <!-- The canvas element can only be manipulated via JavaScript -->
    <div>
      <button id="erase">Erase</button>
      <button id="save">Save</button>
      <button id="load">Load</button>
    </div>
    <script>
      function requiredFeaturesAvailable() {
        return (
                 !!window.addEventListener && // Use the double negative "!!" to force the object to a Boolean value.
                 !!document.createElement('canvas').getContext &&
                 !!window.localStorage
               );
      } // requiredFeaturesAvailable
      
      if ( !requiredFeaturesAvailable() ) {
        document.getElementById('bodyElement').innerHTML = "<h2>Required features are not supported by this browser.</h2><p>To use this application, upgrade your browser to the latest version.</p>";
      }
      else {
        window.addEventListener('load', init, false); // Safety first.
  
        function init() {
          var canvas = document.getElementById('drawSurface'); // A static variable, due to the fact that one or more local functions access it.
          var context = canvas.getContext('2d'); // A static variable, due to the fact that one or more local functions access it.
  
          context.fillStyle = "purple";
  
          if (window.navigator.msPointerEnabled) {
            canvas.addEventListener('MSPointerMove', paintCanvas, false);
          }
          else {
            canvas.addEventListener('mousemove', paintCanvas, false);
          }
  
          document.getElementById('erase').addEventListener('click', eraseCanvas, false);
          document.getElementById('save').addEventListener('click', saveCanvas, false);
          document.getElementById('load').addEventListener('click', loadCanvas, false);
  
          function paintCanvas(event) { // The "event" object contains the position of the pointer/mouse.
            context.fillRect(event.offsetX, event.offsetY, 4, 4); // Draw a 4x4 rectangle at the given coordinates (relative to the canvas box). As of this writing, not all browsers support offsetX and offsetY.
          } // paintCanvas
  
          function saveCanvas() {
            window.localStorage.canvasImage = canvas.toDataURL(); // Save the user's drawing to persistent local storage.
          } // saveCanvas
  
          function eraseCanvas() {
            context.clearRect(0, 0, context.canvas.width, context.canvas.height);
          } // eraseCanvas
  
          function loadCanvas() {
            var img = new Image(); // The canvas drawImage() method expects an image object.
            
            img.src = window.localStorage.canvasImage; // Retrieve the last saved artistic achievement from persistent local storage.
            img.onload = function() { // Only render the saved drawing when the image object has fully loaded the drawing into memory.
              context.drawImage(img, 0, 0); // Draw the image starting at canvas coordinate (0, 0) - the upper left-hand corner of the canvas.
            } // onload
          } // loadCanvas
        } // init
      } // else
    </script>
  </body>
</html>

基本的に、例 2 は、例 1 に次の拡張を加えたものです。

  • 最初に、requiredFeaturesAvailable 関数を使って、すべての必要な機能を見つけます。安全対策として、対象のオブジェクトを二重否定して、オブジェクトをブール値に "キャスト" します。

  • 次に、saveCanvaseraseCanvas の 2 つの新しいイベント ハンドラーを追加します。これらのイベント ハンドラーは、それぞれ [保存] ボタンと [読み込み] ボタンがクリックされたときに呼び出されます。saveCanvas 関数は、次の 1 行から校正されます。

    
    window.localStorage.canvasImage = canvas.toDataURL();
    
    

    これにより、ユーザーの図が Web ページに表示できる形式に変換され、カスタムの canvasImage プロパティ名 (任意の有効な名前を使うことができます) を使ってローカル記憶域に保存されます。

  • [読み込み] ボタンがクリックされたときは、保存された画像を取得し、次のように canvas 上に描画します。canvas.drawImage メソッドには画像を指定するため、最初に新しい汎用画像オブジェクトを作成し、その src 属性を保存された図に設定します (通常はグラフィックス ファイルを指し示す HTTP パスに設定します)。画像オブジェクトからその src が完全に読み込まれたことが通知されたら、canvas.drawImage を起動して画像オブジェクトを canvas 要素に転送します。

図が本当に無期限に保存されることを確かめるために、図を作成し、[保存] をクリックした後、コンピューターを再起動します。例 2 をもう一度開始し、(空白の canvas に誤って描画しないように注意してください) [読み込み] をクリックします。すると、保存した図が表示されます。

Web Storage では、文字列ベースのキー/値ペアしか使用できないことに注意してください。ただし、JSON.stringify() を使うと、生の JavaScript オブジェクトを保存することができます。次の例にその方法を示します。

例 3


<!DOCTYPE html>
<html>
  <head>
    <title>Storing/Retrieving JavaScript Objects Using HTML5 Local Storage</title>
    <meta http-equiv="X-UA-Compatible" content="IE=10">    
  </head>
  <body>
    <h1>Storing Objects using Local Storage</h1>
    <h3>Example 3</h3>
    <p></p>
    <script>
      if (!!window.localStorage) {
        var person = { firstName: 'John', lastName: 'Anderson' }; // Create a JavaScript object literal.

        window.localStorage.person = JSON.stringify(person); // Convert the object to a string.
        person = JSON.parse(window.localStorage.person); // Convert the object string back to a JavaScript object.

        document.querySelector('p').innerHTML = "<strong>First Name:</strong> " + person.firstName + "<br /><strong>Last Name:</strong> " + person.lastName;
      }
      else {
        document.querySelector('body').innerHTML = "<h2>Local storage is not supported by this browser.</h2><p>To use this application, upgrade your browser to the latest version.</p>";
      }
    </script>
  </body>
</html>

演習

この描画アプリは、明らかに最も初期の段階にあるアプリです。このアプリには、少なくとも、描画を開始する前にユーザーに canvas をクリックすることを求め、(マウス/ポインター速度に反応する) "ブロック" 四角形を連続する線に変換するように、改良を加えることをお勧めします。

関連トピック

JSON に関する概要
ローカル ファイルを管理する方法
Internet Explorer 10 のサンプルとチュートリアル
Web ストレージについて
ローカル ファイルを読み取る方法

 

 

表示:
© 2014 Microsoft