title: Accessing indexedDB from code inside a Blob
body: <p>First I've to explain the scenario:</p>
  
  <ul>
  <li>Kiosk web app with CHROMIUM, showing LOCAL webs. That is, no webserver installed. Chromium is always showing "file:///" pages.</li>
  <li>The reason is: sometimes, the computer can be offline (network issues, wifi range...).</li>
  <li>Requirement: we want to use google analytics. When computer is ONLINE, the system send http request to GA normally. When OFFLINE, we want to save http request to indexedDB. </li>
  <li>Using a worker that executes a job each X seconds, we test the Internet connection. If success, the worker gets the http requests saved into indexedDB and send to Google Analytics.</li>
  </ul>
  
  <p>We've achieved all steps, but one: <strong>accesing indexedDB from javascript code inside a Blob</strong>.</p>
  
  <p>The reason to use a js Worker inside a Blob is because Chrome don't allow accesing javascript files when the scenario is locally (File:///). This is a small example of a Worker inside a Blob, that access indexedDb each 3 seconds. The example works great in Firefox, for example. But in Chrome, this exception is launched when executing code that access to indexedDb from Blob code: </p>
  
  <blockquote>
    <p>Unhandled rejection: OpenFailedError: SecurityError Failed to execute
    'open' on 'IDBFactory': access to the Indexed Database API is denied
    in this context.</p>
  </blockquote>
  
  <pre><code>&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;Example error blob and indexeddb&lt;/title&gt;
    &lt;/head&gt;
  
    &lt;body&gt;
      &lt;p&gt;This example demostrate that javascript code inside a Blob can't access indexedDb in Chrome.&lt;/p&gt;
      &lt;p&gt;Click 'Start WebWorker' to create a Worker inside a Blob. This worker tries to insert some&lt;br&gt;
      data into a database created in 'startWorker()' function.&lt;/p&gt;
      &lt;button type="button" onclick="startWorker()" id="btnStart"&gt;
          Start WebWorker
      &lt;/button&gt;
      &lt;button type="button" onclick="stopWorker()" id="btnStop"&gt;
          Stop WebWorker
      &lt;/button&gt;
  
  
    &lt;!-- FOR LOGGING INFO PURPOSES --&gt;
    &lt;p id="demo"&gt;&lt;/p&gt;
  
    &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"&gt;&lt;/script&gt;
  
  
    &lt;!-- TRICK !! Declare this block of type 'javascript/worker' or something non-standard.
        Later we can create on the fly javascript executable code
        using a Blob (see 'window.onload' function later on this file)
    --&gt;
    &lt;script id="worker" type="javascript/worker"&gt;
  
          var started = false;
          var timer;
  
          onmessage = function (event)
          {
              var orden = event.data.toString();
  
              switch (orden)
              {
                  case 'start':
                      start();
                      break;
                  case 'stop':
                      stop();
                      break;
                  default:
                      notRecognized(orden);
                      break;
              }
          }
  
          function start()
          {
              if( ! started)
              {
                timer = setInterval(function(){ job() }, 3000);
                started = true;
              }
          }
  
          function stop()
          {
              if(started)
              {
                  clearInterval(timer);
                  started = false;
              }
          }
  
          //Executed each 3 seconds (see start() )
          function job()
          {
            // Open the database -&gt; ERROR!! Uncaught SecurityError: Failed to execute 'open' on 'IDBFactory':
            //                              access to the Indexed Database API is denied in this context.
            var open = indexedDB.open("MyDatabase", 1);
  
            open.onsuccess = function()
            {
                // Start a new transaction
                var db = open.result;
                var tx = db.transaction("MyObjectStore", "readwrite");
                var store = tx.objectStore("MyObjectStore");
                var index = store.index("NameIndex");
  
                // Add some data
                store.put({id: 12345, name: {first: "John", last: "Doe"}, age: 42});
                store.put({id: 67890, name: {first: "Bob", last: "Smith"}, age: 35});
  
                // Close the db when the transaction is done
                tx.oncomplete = function()
                {
                    db.close();
                };
            }
          }//end job()
  
          function notRecognized(orden)
          {
              var mensaje = 'Comando no reconocido';
              selt.postMessage(mensaje + ': ' + orden);
          }
    &lt;/script&gt;
  
  
  
  
  
  
      &lt;script type="text/javascript"&gt;
  
          var myWorker;
          var workerStarted = false;
  
          //Al cargar la pagina, se llama al onload, que carga el WebWorker
          window.onload = function () {
  
              var blob = new Blob([ document.querySelector('#worker').textContent ], {type : 'text/javascript'});
  
              myWorker = new Worker(window.URL.createObjectURL(blob));
  
              myWorker.onmessage = function (event)
              {
                  document.getElementById("demo").textContent = event.data; //cambiamos el texto del &lt;p&gt;
                  console.log("Got: " + event.data + "\n");
              };
  
              myWorker.onerror = function (error)
              {
                  document.getElementById("demo").textContent = "Worker error: " + error.message;
                  console.log("Worker error: " + error.message + "\n");
                  throw error;
              };
          };//e onload
  
        //click en botón iniciar, mandamos 'start' al worker
        function startWorker()
        {
           if(workerStarted)
           {
              document.getElementById("demo").textContent = "Worker yet started !";
              return;
            }
  
  
            //Create the DataBase
            var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB;
  
            // Open (or create) the database
            var open = indexedDB.open("MyDatabase", 1);
  
            // Create the schema
            open.onupgradeneeded = function() {
                var db = open.result;
                var store = db.createObjectStore("MyObjectStore", {keyPath: "id"});
                var index = store.createIndex("NameIndex", ["name.last", "name.first"]);
            };
  
            workerStarted = true;
  
            //Start Worker
            myWorker.postMessage('start');
        }
  
        //click en botón parar, mandamos 'stop' al worker
        function stopWorker() {
            myWorker.postMessage('stop');
        }
      &lt;/script&gt;
    &lt;/body&gt;
  
    &lt;/html&gt;
  </code></pre>