Salvataggio di file in locale mediante Web Storage

Questo argomento comincia da dove finisce Lettura dei file locali e dimostra come salvare file non di grandi dimensioni localmente usando Web Storage.

Uno dei modi più semplici per salvare localmente file di dimensioni contenute è usare Web Storage. Web Storage è simile ai tradizionali cookie, ma in genere consente l'allocazione di uno spazio di archiviazione più ampio. Internet Explorer 10 consente, ad esempio, di archiviare localmente 10 MG per dominio di stringhe, file, oggetti JavaScript e altri elementi. Gli esempi di codice seguenti mostrano come salvare file localmente usando questa tecnica.

Nota  Per gli esempi di codice seguenti è richiesto un browser che supporti l'API dei file e Web Storage, come Internet Explorer 10 o versioni successive.

Applicazione di disegno Canvas

Per rendere più realistici gli esempi di codice successivi, il primo esempio presenta una semplice applicazione di disegno basata su Canvas HTML5. Queste applicazioni generano la legittima esigenza di salvare i file localmente. Più avanti l'esempio sarà ampliato per consentire il salvataggio locale della produzione artistica dell'utente.

Esempio 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>

Per usare questa semplice applicazione, sposta il mouse sull'area quadrata del Canvas. Per cancellare un disegno basta fare clic sul pulsante Erase.

L'aspetto forse più complesso di questo codice sono le due variabili "statiche", canvas e context, dichiarate come variabili locali all'interno di init. Poiché le funzioni locali (paintCanvas e eraseCanvas) vi accedono, esse sono accessibili dopo la conclusione di init. Questo criterio presenta il vantaggio di non ingombrare lo spazio dei nomi globale. Nota che questa applicazione funziona anche con dispositivi abilitati al tocco, come i tablet.

Salvataggio di file mediante Web Storage

Come abbiamo già detto, i browser attuali (compreso Windows Internet Explorer 9 e versioni successive) supportano Web Storage. Esistono due tipi di Web Storage: locale e di sessione. Come è intuitivo, il secondo persiste solo durante la sessione del browser. L'archiviazione locale, al contrario, permane indefinitamente.

Per salvare il disegno di un utente useremo l'archiviazione locale. L'operazione è relativamente semplice, come il seguente esempio dimostra:

Esempio 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>

L'esempio 2 è essenzialmente l'esempio 1 con le estensioni seguenti:

  • Rileviamo prima se sono presenti tutte le funzionalità che stiamo utilizzando con la funzione requiredFeaturesAvailable. Per precauzione, neghiamo doppiamente gli oggetti di interesse per eseguirne il cast in un valore booleano.

  • Poi aggiungiamo due nuovi gestori eventi, saveCanvas e eraseCanvas, che vengono rispettivamente richiamati quando si fa clic sui pulsanti Save e Load. La funzione saveCanvas consiste in una riga:

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

    Il disegno dell'utente viene convertito in una forma visualizzabile in una pagina Web e quindi salvato nell'archivio locale sotto il nome di proprietà canvasImage personalizzato, che può essere qualsiasi nome valido.

  • Quando l'utente fa clic sul pulsante Load recuperiamo l'immagine salvata e la visualizziamo nel Canvas nel modo seguente: poiché il metodo canvas.drawImage prevede un'immagine, creiamo innanzitutto un nuovo oggetto immagine generico, impostiamo l'attributo src sul disegno salvato (di solito è impostato su un percorso HTTP che punta a un file grafico) e quindi, quando gli oggetti immagine ci dicono che la proprietà src è completamente caricata, lo trasferiamo nell'elemento Canvas richiamando canvas.drawImage.

Per convincerti che il disegno viene realmente salvato in modo permanente, crea un disegno, fai clic su Save, riavvia il computer, riesegui l'esempio 2 e quindi, facendo attenzione a non disegnare accidentalmente sul Canvas vuoto, fai clic su Load: il disegno salvato appare "miracolosamente".

Fra parentesi, tieni presente che Web Storage ti consente solo di archiviare coppie chiave/valore basate su stringhe. Ciò nonostante, è possibile archiviare oggetti JavaScript non elaborati usando JSON.stringify(). L'esempio di codice seguente mostra come fare:

Esempio 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>

Esercizi

Naturalmente l'applicazione di disegno descritta è nella migliore delle ipotesi rudimentale. Sarebbe bene, come minimo, migliorarla in modo che l'utente debba fare clic sul Canvas per poter iniziare a disegnare e che i rettangoli sensibili alla velocità del mouse/puntatore siano sostituiti da linee con flusso contiguo.

Argomenti correlati

Breve panoramica su JSON
Come gestire i file locali
Esempi ed esercitazioni per Internet Explorer 10
Introduzione all'archiviazione Web
Lettura di file locali

 

 

Mostra:
© 2014 Microsoft