aaronpowell / db.js

db.js is a wrapper for IndexedDB to make it easier to work against
http://aaronpowell.github.com/db.js/
MIT License
820 stars 142 forks source link

Throwing errors in module code breaks AMD loaders #182

Open semmel opened 8 years ago

semmel commented 8 years ago

I load db.js as AMD module with RequireJS. When a module throws an exception in it's module definition code the whole module loader breaks. It occurs in this line:

var indexedDB = local.indexedDB || local.webkitIndexedDB || local.mozIndexedDB || local.oIndexedDB || local.msIndexedDB || local.shimIndexedDB || function () {
        throw new Error('IndexedDB required');
    }();

on Firefox if you disable third-party cookies in the settings and access indexedDB from a cross-origin iframe (i.e. simply load db.js via require(['db'], function(db){});. It will throw a SecurityError with code == 18.

I managed to hack around this, but it would be great if the exception would occur not till I actually access the db.js methods.

By the way, great api for IndexedDB. Small, concise and with Promises :clap: :bowtie:

aaronpowell commented 8 years ago

Can you post a jsbin reproducing the error? I'll admit to not having used the AMD stuff in a long time, I stick with ES6 modules and transpile with the likes of babel

semmel commented 8 years ago

Here the jsbin. It just embeds a X-origin iframe which loads db.js and underscore as AMD modules:

require(['db', 'underscore'], function(db, _){
  log("Underscore " + _.VERSION);  // Hello underscore!
  /// Hello db.js!
  db.open({
    server: 'my-app',
    version: 1,
    schema: {
        people: {
            key: {keyPath: 'id', autoIncrement: true},
        }
    }
}).then(function (server) {
    db = server.getIndexedDB();
    log(JSON.stringify(db.objectStoreNames));
    server.close();
});
});

The point is, that on Firefox, with third-party cookies disabled, even the first line log("Underscore " + _.VERSION); never gets executed. Thus the complete app does not run. I guess this is because the AMD loader quits on the SecurityError 18 already during setup of db.js.

On Chrome , with third-party cookies disabled, it is fine: The exception is raised not till db.js is invoked in the lines thereafter. This is because the Chrome team decided to report the security error in the onerror handler of the IndexedDB request instead.

When the browsers are configured to permit third-party cookies the output in the iframe reads

Underscore 1.8.3{"0":"people"}

Disabling cross-domain third-party cookies really helps to protect against user tracking, without sacrificing functionality of web apps. With raising awareness about privacy I guess that is not a rare browser setting.