Tutorial 4: LocalStorage

Door xleeuwx op maandag 16 juni 2014 11:03 - Reacties (14)
CategorieŽn: JS Scripts, PHP Scripts, Views: 6.221

Voorwoordje

Het probleem:
Het vasthouden van gegevens in de browser kan op verschillende manieren, er blijven echter nog maar een paar manieren over waaronder de meest bekende Cookies wat per definitie niet mij voorkeur heeft. Dit wordt nog een groter probleem als je een hele hoop data moet bewaren zoals bijv. een array of zelfs meerderen (in mijn geval).
De oplossing:
Doormiddel van een ajax call data ophalen en opslaan in de localStorage van de browser.
Alternatieven
Hoor ik graag, laat maar in een reactie achter hoe jij denkt dat dit beter opgelost kan worden.

De tutorial

Ik heb drie files aangemaakt, de eerste is de standaard index.php. De tweede is het javascript bestand. En het derde is de ajax handler.
Index.php
De monster file der monster file: html ... met macht der gewoonte maak ik eigelijk standaard een index.php inplaats van een index.html :)


HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
    <head>
        <title>Tutorial 4 - Localstorage playground</title>
        <script src="includes/localstorage.js"></script>
    </head>
    <body>
        <div id="wrapper">      
            <h2>Request Data:</h2>
            <div id="ajax_output">
            </div>
            <h2>Localstorage Data:</h2>
            <div id="ls_output">
            </div>
        </div>
    </body>
</html>

getData.ajax.php
Ook deze file is niet groot en maakt eigelijk alleen maar test data aan, eerst maken we met een loopje en nog een loopje een multi dimensionale array aan. Vervolgens maken we er een mooie string van met json_encode met de optie JSON_FORCE_OBJECT om er voor te zorgen dat JavaScript het ook goed oppakt.

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php

$data = array();

## -- Make the array of data
for($i=0; $i < 10; $i++) {
    $data[$i] = array();
    for($y=0; $y < 10; $y++) {
        $data[$i][$y] = rand(1,1000);
    }
}

if(isset($_GET['data']) && intval($_GET['data']) > 0) {
    echo json_encode($data, JSON_FORCE_OBJECT);
}

?>

localStorage.js
En hier gaat het allemaal gebeuren, ik heb expres voor gekozen om geen jQuery te gebruiken maar gewoon ouderwetse xmlhttp request, documentatie: w3Schools of beter MDN . Verder gebeurt alles gewoon als de pagina geladen wordt, niks spanneds aan. Als eerste word de data opgehaald van de php file daarna word er een check uitgevoerd om te kijken of de browser LocalStorage onderdsteund, als dit zo is gaan we door met de data in de localStorage te zetten en deze vervolgens weer uit te lezen.


JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
var xmlHttp;
try { xmlHttp=new XMLHttpRequest(); } catch (e) {
try { xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) {
try { xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {
}}} 

var ls = localstorageSupport();



window.onload = function() {
    getData();

    // setData();
};

function getData() {
    xmlHttp.onreadystatechange=function() {
        if (xmlHttp.readyState==4 && xmlHttp.status==200) {
            if(ls) {
                // Set localstorage
                    setLocalstorage('test', xmlHttp.responseText);
                    
                // Set data to screen
                    document.getElementById("ajax_output").innerHTML = xmlHttp.responseText;
                    
                // Set localStorage to screen and stringify for same result as above
                    var data = getLocalstorage('test');
                    document.getElementById("ls_output").innerHTML = JSON.stringify(data);
            } else {
                // Set data to screen
                    document.getElementById("ajax_output").innerHTML = xmlHttp.responseText;
                    
                // Set to screen no ls support
                    document.getElementById("ls_output").innerHTML = 'LocalStorage is not supported by your browser please delete this browser to avoid problems in the future';
            }
        }
    }           
    xmlHttp.open("GET", "/tweakers/tutorial_4/includes/getData.ajax.php?data="+returnTime(), true);
    xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlHttp.send();
}

function setData() {
    // Check localstorage support           
        if(ls) {                
            // Set localStorage to screen and stringify for same result as above
                var data = getLocalstorage('test');             
                document.getElementById("ls_output").innerHTML = JSON.stringify(data);
        } else {                
            // Set to screen no ls support
                document.getElementById("ls_output").innerHTML = 'LocalStorage is not supported by your browser please delete this browser to avoid problems in the future';
        }
}

function localstorageSupport() {
    if(typeof(Storage) !== void(0)) {
        return true;
    }
    return false;
}

function returnTime() {
    // Create time (int)
        return (new Date()).getTime();
}

function setLocalstorage(key, value) {
    // Check if key and value exists
        if(typeof key !== 'undefined' && typeof value !== 'undefined' && key !== '' && value !== '') {
            // localstorage set     
                localStorage.setItem(key, value);   
        }
}

function getLocalstorage(key) {
    // Get localstorage 
        var data = localStorage.getItem(key)
    
    // Check if exists
        if(typeof data !== 'undefined') {
            // unserialize data
            data = JSON.parse(data);
            // Return the value of key
            return data;
        }
        
    //  Return false
        return false;
}




En als we in de browser nu af zouden sluiten en daarna weer opstarten staat de data nog steeds in de localStorage. Dit kunnen we testen door de setData(); uit te quote en getData(); weer te activeren:

JavaScript:
1
2
3
4
5
window.onload = function() {
    // getData();

    setData();
};



En nu zien we ook dat de request leeg is en de localStorage gevult, en je browser afsluiten gaat hem niet leeghalen :). Veel plezier hiermee en mochten er nog vragen of opmerkeningen zijn hoor ik ze graag.

Volgende week

Volgende week ga ik met php een xml aanmaken op basis van array (puur omdat ik lui ben en array 's lekkerder vind werken als objects)

Volgende: Tutorial 5: Array to xml 06-'14 Tutorial 5: Array to xml
Volgende: Tutorial 3: DNS records ophalen 06-'14 Tutorial 3: DNS records ophalen

Reacties


Door Tweakers user everlaat, maandag 16 juni 2014 12:29

Top dat je de moeite neemt om zo een tutorial te schrijven, mooi ook dat je geen framework gebruikt voor een tutorial zoals deze!
Mijn opmerking; gebruik geen w3schools (http://www.w3fools.com/) ze putten vaak uit achterhaalde bronnen, MDN is een stuk beter als bron; https://developer.mozilla...Web/Guide/API/DOM/Storage

Door Tweakers user xleeuwx, maandag 16 juni 2014 13:19

everlaat schreef op maandag 16 juni 2014 @ 12:29:
Top dat je de moeite neemt om zo een tutorial te schrijven, mooi ook dat je geen framework gebruikt voor een tutorial zoals deze!
Mijn opmerking; gebruik geen w3schools (http://www.w3fools.com/) ze putten vaak uit achterhaalde bronnen, MDN is een stuk beter als bron; https://developer.mozilla...Web/Guide/API/DOM/Storage
Inderdaad heb je gelijk in, heb het ook even aangepast.

Door Tweakers user robkorv, maandag 16 juni 2014 22:12

Toevallig heb ik localstorage recent gebruikt om instellingen van een filter op te slaan in de client ipv server side.

Ik heb hiervoor http://mozilla.github.io/localForage/ gebruikt. Deze is asynchroon en als indexeddb of websql niet beschikbaar is doet hij een fallback naar een systeem dat wel aanwezig is.

[Reactie gewijzigd op maandag 16 juni 2014 22:13]


Door Tweakers user -RetroX-, dinsdag 17 juni 2014 09:04

Wat is nu eigenlijk het grote voordeel van LocalStorage?

Door Tweakers user xleeuwx, dinsdag 17 juni 2014 09:27

robkorv schreef op maandag 16 juni 2014 @ 22:12:
Toevallig heb ik localstorage recent gebruikt om instellingen van een filter op te slaan in de client ipv server side.

Ik heb hiervoor http://mozilla.github.io/localForage/ gebruikt. Deze is asynchroon en als indexeddb of websql niet beschikbaar is doet hij een fallback naar een systeem dat wel aanwezig is.
Inderdaad is een voordeel, echter probeer ik altijd zo veel mogelijk in plain JavaScript / PHP te blijven. Maar dit is inderdaad wel een mooie library
-RetroX- schreef op dinsdag 17 juni 2014 @ 09:04:
Wat is nu eigenlijk het grote voordeel van LocalStorage?
Ik zie Localstorage als alternatief van de cookies (tenzij je nog serverside bij de data moet), Aangezien je meer opslag ruimte hebt dan bij cookies en het sneller is dan cookies (geen overhead met http headers). Daarnaast verschild het nog per device hoeveel je mag opslaan in de Localstorage.

Localstorage is ook onbeperkt geldig tot je de browser cache weghaalt of met javascript de storage leeghaald. Terwijl een cookie verloopt.

Daarnaast werkt het ook mooi om bijvoorbeeld een webapp te maken die offline beschikbaar moet wezen. als de browser weer online komt kan je syncen met de server en daarna de Localstorage als database gebruiken

[Reactie gewijzigd op dinsdag 17 juni 2014 09:30]


Door Tweakers user -RetroX-, dinsdag 17 juni 2014 10:39

De verlooptijd bij cookies is ook wel aan te passen, dat zal het verschil niet maken.

De offline webapp is inderdaad wel een mooie toepassing. Ik zie nog wel een voordeel als bij uploads (bv foto's) met LS als buffer. Zolang je op je bundel zit (3G/4G) dat soort meuk in je LS en bij wifi daadwerkelijk uploaden.

Door Tweakers user xleeuwx, dinsdag 17 juni 2014 10:50

-RetroX- schreef op dinsdag 17 juni 2014 @ 10:39:
De verlooptijd bij cookies is ook wel aan te passen, dat zal het verschil niet maken.

De offline webapp is inderdaad wel een mooie toepassing. Ik zie nog wel een voordeel als bij uploads (bv foto's) met LS als buffer. Zolang je op je bundel zit (3G/4G) dat soort meuk in je LS en bij wifi daadwerkelijk uploaden.
Vergeet niet dat je niet zoveel foto's kan vasthouden in de localstorage, volgens mij iets van 5MB

Door Tweakers user TERW_DAN, dinsdag 17 juni 2014 12:19

Maar je localstorage kan toch alleen overweg met stringdata? Of is dat tegenwoordig weer anders?
Dus daar foto's inmikken is dan toch weer wat lastiger lijkt me.

Door Tweakers user xleeuwx, dinsdag 17 juni 2014 12:52

TERW_DAN schreef op dinsdag 17 juni 2014 @ 12:19:
Maar je localstorage kan toch alleen overweg met stringdata? Of is dat tegenwoordig weer anders?
Dus daar foto's inmikken is dan toch weer wat lastiger lijkt me.
Ja het kan wel... maar niet in alle browsers, het kan bijvoorbeeld met Canvas
https://developer.mozilla...Web/API/HTMLCanvasElement

Door Tweakers user robkorv, dinsdag 17 juni 2014 12:54

TERW_DAN schreef op dinsdag 17 juni 2014 @ 12:19:
Maar je localstorage kan toch alleen overweg met stringdata? Of is dat tegenwoordig weer anders?
Dus daar foto's inmikken is dan toch weer wat lastiger lijkt me.
Je kan data serializen met bijv base64. Localforage doet het serializen voor je.

Door Tweakers user xleeuwx, dinsdag 17 juni 2014 17:35

TERW_DAN schreef op dinsdag 17 juni 2014 @ 12:19:
Maar je localstorage kan toch alleen overweg met stringdata? Of is dat tegenwoordig weer anders?
Dus daar foto's inmikken is dan toch weer wat lastiger lijkt me.
Ik kan misschien wel kijken of ik daar me tutorial 6 aan kan besteden ;)

Plaatje opslaan in LS en daarna via ajax in MySQL zetten :)

Door Tweakers user photonios, dinsdag 17 juni 2014 22:15

Ziet er goed uit! Meer technische stuff!

Misschien goed om ook het verschil tussen sessionStorage, localStorage en globalStorage uit te leggen?

Ik mis trouwens wel wat error handeling; in 'setLocalstorage' wordt een potentiele error volledig verborgen...

[Reactie gewijzigd op dinsdag 17 juni 2014 22:17]


Door Tweakers user xleeuwx, woensdag 18 juni 2014 00:38

photonios schreef op dinsdag 17 juni 2014 @ 22:15:
Ziet er goed uit! Meer technische stuff!

Misschien goed om ook het verschil tussen sessionStorage, localStorage en globalStorage uit te leggen?

Ik mis trouwens wel wat error handeling; in 'setLocalstorage' wordt een potentiele error volledig verborgen...
Inpreciepe mag er niks fout gaan er word namelijk al eerst gekeken of de browser LS ondersteund maar hij kan natuurlijk vol zitten.

Door Tweakers user Jogai, zaterdag 21 juni 2014 15:01

Voor simpele storage zou is store.js ook handig: https://github.com/marcuswestin/store.js

Voor geavanceerdere use-cases zou ik eerder sdb oid pakken: https://github.com/cScarlson/SDB

Reageren is niet meer mogelijk