Defold apps not loading in sandboxed iframe in Firefox

This is a blank project with zero changes bundled for HTML and put into a sandboxed iframe.

https://www.pkeod.com/firefox/

In Chrome it works, but in Firefox it does not.

Uncaught TypeError: Module.asm is undefined

I need to ship a project VERY SOON and this surprise sucks, anyone know of what can be done to fix this or at least detect it so I can put up a “Browser not Supported, use Chrome” message?

Not sure why it isn’t working. I’ll take a look in a few hours.

1 Like

Ok, so there’s two errors and I bet they are related:

This line:

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;

Modifying the window like that from within an iframe is probably not allowed. You can try hacking your way around it. Replace preInit with:

    preInit: [function() {
        /* Mount filesystem on preinit */
        var dir = DMSYS.GetUserPersistentDataRoot();
        FS.mkdir(dir);

        Module._preloadAndCallMain();
    }],

Save games will not work I guess, but the game should start. You can perhaps also try not writing to window:

    preInit: [function() {
        /* Mount filesystem on preinit */
        var dir = DMSYS.GetUserPersistentDataRoot();
        FS.mkdir(dir);

        // If IndexedDB is supported we mount the persistent data root as IDBFS,
        // then try to do a IDB->MEM sync before we start the engine to get
        // previously saved data before boot.
        var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
        if (Module.persistentStorage && indexedDB) {
            FS.mount(IDBFS, {}, dir);

            // Patch FS.close so it will try to sync MEM->IDB
            var _close = FS.close; FS.close = function(stream) { var r = _close(stream); Module.persistentSync(); return r; }

            // Sync IDB->MEM before calling main()
            Module.preSync(function() {
                Module._preloadAndCallMain();
            });
        } else {
            Module._preloadAndCallMain();
        }
    }],
2 Likes

This is normal for these kinds of heavily sandboxed iframes. Saving doesn’t work on Chrome either but it also doesn’t break like with Firefox.

It does now on Firefox, thank you!

May I ask which of the two alternatives you tried?

This one

    preInit: [function() {
        /* Mount filesystem on preinit */
        var dir = DMSYS.GetUserPersistentDataRoot();
        FS.mkdir(dir);

        Module._preloadAndCallMain();
    }],

I didn’t try it yet but maybe try/catch on the functions Firefox doesn’t like could prevent it from not allowing the game to run at all. Could also add a check to see if iframe is sandboxed somehow.

I tried the second option now to test and it does still cause the issue.

I tried doing this but it didn’t help

    preInit: [function() {
        /* Mount filesystem on preinit */
        var dir = DMSYS.GetUserPersistentDataRoot();
        FS.mkdir(dir);

		try {
			// If IndexedDB is supported we mount the persistent data root as IDBFS,
			// then try to do a IDB->MEM sync before we start the engine to get
			// previously saved data before boot.
			window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
			if (Module.persistentStorage && window.indexedDB) {
				FS.mount(IDBFS, {}, dir);

				// Patch FS.close so it will try to sync MEM->IDB
				var _close = FS.close; FS.close = function(stream) { var r = _close(stream); Module.persistentSync(); return r; }

				// Sync IDB->MEM before calling main()
				Module.preSync(function() {
					Module._preloadAndCallMain();
				});
			} else {
				Module._preloadAndCallMain();
			}
		} catch (error) {
			console.log('Error caught: ', error);
			Module._preloadAndCallMain();
		}
    }],

Apparently “Uncaught TypeError” do not fall within scope of try/catch.

A fix for this and related issues have been merged: https://github.com/defold/defold/pull/7603

You should be able to try this yourself by replacing your dmloader.js with the new one:

3 Likes

Tested with that version and confirmed no longer breaking within sandboxed iframes in Firefox!

4 Likes