gnorkus
gnorkus

Reputation: 31

Use of localStorage and IndexedDB in New Google Sites <Embed HTML> doesn't work

I'm trying to make use of the New Google Sites for a web page that I've developed, however, I'm having trouble storing local data. Local files work fine in windows and apple safari/chrome. Try it from Google Sites, and no joy! Additionally, in safari, an error is thrown, "IDBFactory.open() called in an invalid security context".

I really would like to host my site via google sites without linking to another server. I specifically need locally persistent data for just a few small items. I can't seem to make cookies work either.

Any suggestions?

I have tried this on a Windows 10 Surface Pro 2017, Apple iPad running 12.2 of Safari, Apple Mac Mini running macOs Mojave 10.14. I use SimpleHTTPServer from Windows 10 command line to share the files as a web server. I also email the files and open directly on the specified systems. Finally, I have created a New Google Sites website at https://sites.google.com/view/gerrymap It's very simple, just an Embed HTML element with the below text copied into the source code edit box. All are welcome to hit that page if they desire. Otherwise, use the short posted file below.

Instructions are in the HTML page itself.

All code works fine from a local instance of the html file. Can enter new values for the lat, long, rad, and key, save them, and read them. I can also refresh the page, then read them without storing first, and there is no problem. This proves that the values aren't just session persistent.

From Google Sites is a different matter. I set up a site that uses the html file in this question. When I enter new values and press the save button, IndexedDB fails, but localStorage succeeds in returning the values saved. If I press the refresh button, however, and then read the values without attempting to store first, IndexedDB again fails, but localStorage also fails in that it doesn't retrieve any values.

I believe I've correctly implemented the code (although some out there may take exception, I'm sure. No pride here, critics are welcome).

I've done a bunch of google searches, particularly about google sites and indexeddb/localstorage, and also posted on the google community help forum. Still no success.

Currently, I have no fallback methods, but need something relatively simple. Can anyone throw a little joy my way? Thanks in advance!


<!DOCTYPE html>
<head>
    <meta charset="utf-8">
    <title>Test Local Storage</title>
    <style>
    </style>
</head>

<body onload="initializeValues()">
    Instructions:  <br />
    1.  Save this sample code in an html file locally and open in a browser.<br />
    2.  Enter different values into the lat, long, rad, and key edit boxes.<br />
    3.  Press TrySave to store the values in indexedDB and localStorage.<br />
    4.  Refresh the webpage from the browser address line<br />
    5.  Press the individual Try IndexedDB and Try LocalStorage buttons to attempt<br />
    6.  Try inserting this code into a New Google Site, or access https://sites.google.com/view/gerrymap/home <br />
    <br>
    <input id="latitude" /> Latitude<br><br>
    <input id="longitude" /> Longitude<br><br>
    <input id="radius" /> Radius<br><br>
    <input id="key" /> Key<br><br>

    <button onclick="TryIndexedDB()" title="This tries to load via IndexedDB">Try IndexedDB</button><br><br>
    <button onclick="TryLocalStorage()" title="This tries to load via localStorage">Try localStorage</button><br><br>
    <button onclick="trySave()" title="This tries to save the data in both methods (IndexedDB, localStorage)">Try Save</button><br><br>
    <button onclick="clearAll()" title="Clear the log space at the bottom of this example page">Clear Log</button><br><br>

    <div id="hello">
    </div>

    <script>
        "use strict";

        function clearAll() {
            document.getElementById("hello").innerHTML = "";
        }

        // tagBeginDefaultsReplace
        var navLatitude = 39;
        var navLongitude = -76.7;
        var navMaxDist = 200;
        var navKey = "PleaseAddYourKey";

        function initializeValues() {
            document.getElementById("latitude").value = navLatitude;
            document.getElementById("longitude").value = navLongitude;
            document.getElementById("radius").value = navMaxDist;
            document.getElementById("key").value = navKey;
        }

        function trySave() {
            navLatitude = document.getElementById("latitude").value;
            navLongitude = document.getElementById("longitude").value;
            navMaxDist = document.getElementById("radius").value;
            navKey = document.getElementById("key").value;

            // Save using indexeddb
            getLocationDB(true, FinishIndexedDB);
            // Save using localStorage
            localStorage.setItem('latitude', navLatitude.toString());
            localStorage.setItem('longitude', navLongitude.toString());
            localStorage.setItem('radius', navMaxDist.toString());
            localStorage.setItem('key', navKey.toString());
            mylog("Done saving localStorage");
        }

        function getLocationDB(bSave, callbackf) {
            var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB || window.shimIndexedDB;
            var openDB;

            try {
                var myitem;

                openDB = indexedDB.open("SampleDatabase", 1);
                openDB.onupgradeneeded = function () {
                    var db = openDB.result;
                    var store = db.createObjectStore("SampleStore", { keyPath: "id" });
                    var index = store.createIndex("PosIndex", ["pos.latitude", "pos.longitude", "pos.radius", "pos.navkey"]);
                };

                openDB.onsuccess = function () {
                    // Start a new transaction var db = openDB.result;
                    callbackf("Successfully opened openDB");
                    var db = openDB.result;
                    var tx = db.transaction("SampleStore", "readwrite");
                    var store = tx.objectStore("SampleStore");
                    if (bSave) {
                        if (navLatitude != undefined && navLongitude != undefined && navMaxDist != undefined)
                            store.put({ id: 0, pos: { latitude: navLatitude, longitude: navLongitude, radius: navMaxDist, navkey: navKey } });
                        else
                            store.put({ id: 0, pos: { latitude: "38", longitude: "-75.7", radius: "100", navkey: "Please Enter Mapbox Key" } });
                        callbackf("Save indexeddb finished");
                    }
                    else {
                        var getNavLoc = store.get(0);

                        getNavLoc.onsuccess = function () {
                            if (getNavLoc != undefined
                                && getNavLoc.result != undefined) {
                                callbackf("Succeeded reading from store.  Result=" + JSON.stringify(getNavLoc.result));
                                navLatitude = parseFloat(getNavLoc.result.pos.latitude);
                                navLongitude = parseFloat(getNavLoc.result.pos.longitude);
                                navMaxDist = parseFloat(getNavLoc.result.pos.radius);
                                navKey = getNavLoc.result.pos.navkey;
                            }
                            else {
                                callbackf("Succeeded reading from store.  Result=undefined");
                                navLatitude = navLongitude = navMaxDist = navKey = "undef";
                            }
                            initializeValues();
                        }


                        getNavLoc.onerror = function () {
                            callbackf("An error occurred getting indexeddb");
                        }

                    }
                }

                openDB.onerror = function () {
                    callbackf("An error occurred opening openDB");
                }
            }
            catch (e) {
                callbackf("Caught error in try block of indexeddb:  " + e.Message);
            }

        }

        function TryIndexedDB() {
            getLocationDB(false, FinishIndexedDB);
        }

        function TryLocalStorage() {
            mylog("localStorage read");
            navLatitude = localStorage.getItem('latitude');
            mylog("latitude=" + navLatitude);
            navLongitude = localStorage.getItem('longitude');
            mylog("longitude=" + navLongitude);
            navMaxDist = localStorage.getItem('radius');
            mylog("radius=" + navMaxDist);
            navKey = localStorage.getItem('key');
            mylog("key=" + navKey);
            if (navLatitude == undefined)
                navLatitude = "undef";
            if (navLongitude == undefined)
                navLongitude = "undef";
            if (navMaxDist == undefined)
                navMaxDist = "undef";
            if (navKey == undefined)
                navKey = "undef";
            initializeValues();
        }

        function FinishIndexedDB(nSucceeded) {
            mylog(nSucceeded);
        }

        function mylog(logstr) {
            document.getElementById("hello").innerHTML += "<br>" + logstr.toString();
        }

    </script>
</body>
</html >
 

Upvotes: 3

Views: 1854

Answers (1)

Herohtar
Herohtar

Reputation: 5613

The problem is the way Google Sites is serving the iframe content. I'm not sure of the exact details behind the scenes, but it seems to have a randomly generated domain every time the page loads. Since localStorage and IndexedDB are associated with a specific domain, this causes the saved data to be "lost" when the page reloads.

As an example, here is the iframe's data from when I first loaded the page:

first load

And here is the iframe's data after refreshing the page:

after refresh

As you can see, the domain is completely different after refreshing, which means it has a brand new empty database.

Upvotes: 1

Related Questions