Local Storage

Bentornato.
Nella lezione precedente hai imparato form e validazione.
I form raccolgono dati dell’utente.
La validazione controlla se quei dati hanno senso.
Molto utile.
Molto responsabile.
Molto “per favore non scrivere banana come email.”
Oggi insegniamo a JavaScript una cosa molto interessante.
La memoria.
Non una vera memoria umana.
JavaScript non ricorderà il tuo compleanno portando una torta.
Ma può ricordare piccoli pezzi di dati nel browser.
Questo si chiama local storage.
Local storage permette a JavaScript di salvare dati anche dopo il refresh della pagina.
Questo significa che la pagina può ricordare cose come:
- il nome dell’utente;
- una preferenza del tema;
- una lista di attività;
- una semplice impostazione;
- piccoli dati di un form.
Prima di local storage, JavaScript dimentica tutto quando la pagina si ricarica.
Dopo local storage, JavaScript diventa leggermente meno smemorato.
Ancora caotico.
Ma sta migliorando.
Cosa Imparerai
In questa lezione imparerai:
- che cos’è local storage;
- come salvare dati con
localStorage.setItem; - come leggere dati con
localStorage.getItem; - come rimuovere dati con
localStorage.removeItem; - come cancellare tutto local storage;
- perché local storage salva stringhe;
- come salvare oggetti e array con
JSON.stringify; - come leggere oggetti e array con
JSON.parse; - come costruire un piccolo salvatore di nome;
- come costruire una semplice lista di attività che sopravvive al refresh.
Alla fine di questa lezione, la tua pagina JavaScript saprà ricordare dati semplici.
Non tutto.
Non segreti.
Non password.
Ma abbastanza per essere utile.
Come un piccolo taccuino dentro il browser.
Che Cos'è Local Storage?
Local storage è una funzione del browser che permette ai siti di salvare piccole quantità di dati.
I dati restano nel browser anche dopo:
- refresh della pagina;
- chiusura della scheda;
- riapertura del browser.
Esempio:
localStorage.setItem("name", "Viktor");
Questo salva il valore "Viktor" con la chiave "name".
Poi possiamo leggerlo più tardi:
const name = localStorage.getItem("name");
console.log(name);
Output:
Viktor
Il browser ha ricordato il valore.
Molto bello.
Molto comodo.
Leggermente magico.
Ma è sempre solo JavaScript.
Avviso Importante
Non salvare dati sensibili in local storage.
Non salvare:
- password;
- token che non capisci;
- documenti privati;
- informazioni bancarie;
- API key segrete;
- qualsiasi cosa che ti farebbe sudare se qualcuno la vedesse.
Local storage non è uno storage sicuro.
È utile per dati semplici.
Una preferenza del tema?
Va bene.
Una lista di attività?
Va bene.
Una password?
No.
Assolutamente no.
La sicurezza non è una pianta decorativa.
Conta davvero.
Crea il Progetto
Crea una cartella per questa lezione:
mkdir javascript-lesson10
cd javascript-lesson10
touch index.html
touch script.js
Il progetto dovrebbe essere così:
javascript-lesson10/
index.html
script.js
Apri la cartella nel tuo editor.
Oggi salveremo dati nel browser.
Il browser sta per diventare un piccolo taccuino.
Speriamo non troppo disordinato.
Scrivi l'HTML
Apri index.html e aggiungi questo:
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Local Storage</title>
</head>
<body>
<h1>Local Storage</h1>
<button id="saveButton">Salva Nome</button>
<button id="loadButton">Carica Nome</button>
<p id="message">Niente caricato ancora.</p>
<script src="script.js"></script>
</body>
</html>
Questo ci dà:
- un pulsante salva;
- un pulsante carica;
- un’area messaggio.
Semplice.
Piccolo.
Pronto a ricordare qualcosa.
Che è più di quanto posso dire di certi browser dopo 38 schede aperte.
Salvare Dati con setItem
Apri script.js e aggiungi:
const saveButton = document.getElementById("saveButton");
const loadButton = document.getElementById("loadButton");
const messageElement = document.getElementById("message");
function saveName() {
localStorage.setItem("name", "Viktor");
messageElement.textContent = "Nome salvato.";
}
saveButton.addEventListener("click", saveName);
Aggiorna il browser.
Clicca Salva Nome.
Il messaggio dovrebbe dire:
Nome salvato.
Questa riga è importante:
localStorage.setItem("name", "Viktor");
Significa:
Salva il valore "Viktor" usando la chiave "name".
Local storage funziona con coppie chiave-valore.
Una chiave è come un’etichetta.
Un valore è il dato.
Come l’etichetta di un cassetto e la cosa dentro il cassetto.
Molto organizzato.
Sospettosamente organizzato.
Leggere Dati con getItem
Ora aggiungi questa funzione:
function loadName() {
const savedName = localStorage.getItem("name");
messageElement.textContent = `Nome salvato: ${savedName}`;
}
loadButton.addEventListener("click", loadName);
Ora il tuo script.js completo è così:
const saveButton = document.getElementById("saveButton");
const loadButton = document.getElementById("loadButton");
const messageElement = document.getElementById("message");
function saveName() {
localStorage.setItem("name", "Viktor");
messageElement.textContent = "Nome salvato.";
}
function loadName() {
const savedName = localStorage.getItem("name");
messageElement.textContent = `Nome salvato: ${savedName}`;
}
saveButton.addEventListener("click", saveName);
loadButton.addEventListener("click", loadName);
Clicca Salva Nome.
Aggiorna la pagina.
Clicca Carica Nome.
Il nome è ancora lì.
JavaScript lo ha ricordato.
La pagina si è aggiornata.
I dati sono sopravvissuti.
Piccolo miracolo.
Niente backend.
Niente database.
Solo il browser che fa cose da browser.
E Se i Dati Non Esistono?
Se provi a leggere una chiave che non esiste, ottieni null.
Esempio:
const savedAge = localStorage.getItem("age");
console.log(savedAge);
Output:
null
null significa:
Qui non c’è niente.
Quindi è meglio controllare prima di mostrare dati.
Esempio:
function loadName() {
const savedName = localStorage.getItem("name");
if (savedName === null) {
messageElement.textContent = "Nessun nome salvato.";
return;
}
messageElement.textContent = `Nome salvato: ${savedName}`;
}
Ora la pagina si comporta meglio.
Se non c’è un nome salvato, lo dice.
Molto educato.
Molto civile.
A differenza di certi errori JavaScript a mezzanotte.
Salvare Input dell'Utente
Scrivere "Viktor" direttamente nel codice va bene per imparare.
Ma di solito vogliamo salvare ciò che l’utente scrive.
Aggiorna index.html:
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Local Storage</title>
</head>
<body>
<h1>Local Storage</h1>
<label for="nameInput">Il tuo nome:</label>
<input id="nameInput" type="text" placeholder="Scrivi il tuo nome">
<button id="saveButton">Salva Nome</button>
<button id="loadButton">Carica Nome</button>
<button id="removeButton">Rimuovi Nome</button>
<p id="message">Niente caricato ancora.</p>
<script src="script.js"></script>
</body>
</html>
Ora aggiorna script.js:
const nameInput = document.getElementById("nameInput");
const saveButton = document.getElementById("saveButton");
const loadButton = document.getElementById("loadButton");
const removeButton = document.getElementById("removeButton");
const messageElement = document.getElementById("message");
function saveName() {
const name = nameInput.value.trim();
if (name === "") {
messageElement.textContent = "Scrivi prima un nome.";
return;
}
localStorage.setItem("name", name);
messageElement.textContent = "Nome salvato.";
nameInput.value = "";
}
function loadName() {
const savedName = localStorage.getItem("name");
if (savedName === null) {
messageElement.textContent = "Nessun nome salvato.";
return;
}
messageElement.textContent = `Nome salvato: ${savedName}`;
}
function removeName() {
localStorage.removeItem("name");
messageElement.textContent = "Nome rimosso.";
}
saveButton.addEventListener("click", saveName);
loadButton.addEventListener("click", loadName);
removeButton.addEventListener("click", removeName);
Ora l’utente può scrivere un nome.
Salvarlo.
Aggiornare.
Caricarlo di nuovo.
Rimuoverlo.
Questo è uso reale di local storage.
Piccolo.
Pratico.
Utile.
Come un taccuino tascabile, ma con più parentesi graffe.
Rimuovere Dati con removeItem
Questa riga rimuove un elemento salvato:
localStorage.removeItem("name");
Rimuove il valore salvato sotto la chiave "name".
Solo quell’elemento.
Non tutto.
Questo è utile quando l’utente vuole resettare una sola impostazione.
Esempio:
localStorage.removeItem("theme");
localStorage.removeItem("username");
localStorage.removeItem("draft");
Specifico.
Controllato.
Senza distruzione inutile.
Molto maturo.
Per JavaScript.
Cancellare Tutto Local Storage
Esiste anche:
localStorage.clear();
Questo rimuove tutto ciò che è salvato in local storage per quel sito.
Tutto.
Tutte le chiavi.
Tutti i valori.
Spariti.
Usalo con attenzione.
Esempio:
function clearStorage() {
localStorage.clear();
}
È utile per pulsanti di reset.
Ma non usarlo a caso.
È l’equivalente digitale di pulire la scrivania con un lanciafiamme.
Efficace.
Ma aggressivo.
Local Storage Salva Stringhe
Dettaglio importante.
Local storage salva i valori come stringhe.
Esempio:
localStorage.setItem("age", 33);
const age = localStorage.getItem("age");
console.log(age);
console.log(typeof age);
Output:
33
string
Anche se abbiamo salvato un numero, local storage ci restituisce una stringa.
Questo conta.
Se ti serve un numero, convertilo:
const age = Number(localStorage.getItem("age"));
JavaScript ama le sorprese di tipo.
Tieni gli occhi aperti.
E magari un sopracciglio alzato.
Salvare Oggetti
Local storage non può salvare direttamente oggetti.
Questo non funziona come vorresti:
const user = {
name: "Viktor",
role: "Student"
};
localStorage.setItem("user", user);
Il risultato diventa qualcosa tipo:
[object Object]
Molto inutile.
Molto JavaScript.
Per salvare un oggetto, trasformalo in stringa con JSON.stringify.
Esempio:
const user = {
name: "Viktor",
role: "Student"
};
localStorage.setItem("user", JSON.stringify(user));
Ora l’oggetto è salvato come stringa JSON.
JSON è un formato testuale per dati.
Assomiglia agli oggetti JavaScript.
Ma è testo.
Piccola differenza.
Grande importanza.
Leggere Oggetti
Per leggere l’oggetto, usa JSON.parse.
Esempio:
const savedUser = localStorage.getItem("user");
const user = JSON.parse(savedUser);
console.log(user.name);
console.log(user.role);
Output:
Viktor
Student
Esempio completo:
const user = {
name: "Viktor",
role: "Student"
};
localStorage.setItem("user", JSON.stringify(user));
const savedUser = localStorage.getItem("user");
const parsedUser = JSON.parse(savedUser);
console.log(parsedUser);
Lo schema è:
JSON.stringify(data)
quando salvi.
JSON.parse(data)
quando leggi.
Stringify per salvare.
Parse per usare.
Semplice.
Potente.
Leggermente cerimoniale.
Salvare Array
Anche gli array hanno bisogno di JSON.stringify.
Esempio:
const tasks = ["Imparare JavaScript", "Praticare DOM", "Bere caffè"];
localStorage.setItem("tasks", JSON.stringify(tasks));
Per leggerli:
const savedTasks = localStorage.getItem("tasks");
const tasks = JSON.parse(savedTasks);
console.log(tasks);
Output:
["Imparare JavaScript", "Praticare DOM", "Bere caffè"]
Questo è molto utile.
Perché molte app salvano liste.
Attività.
Prodotti.
Preferiti.
Impostazioni.
Piccole liste di cose importanti per l’utente.
E a volte liste di cose che l’utente dimenticherà comunque.
Ma il browser ricorda.
Costruire una Lista di Attività Persistente
Ora costruiamo una piccola lista di attività che sopravvive al refresh.
Aggiorna index.html:
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Local Storage</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 700px;
margin: 60px auto;
padding: 0 24px;
background-color: #f3f4f6;
color: #111827;
}
.card {
background-color: white;
padding: 24px;
border: 2px solid #e5e7eb;
border-radius: 18px;
}
h1 {
font-size: 42px;
}
input {
width: 100%;
margin-top: 8px;
padding: 12px;
border: 2px solid #d1d5db;
border-radius: 12px;
font-size: 18px;
box-sizing: border-box;
}
button {
margin-top: 14px;
background-color: #2563eb;
color: white;
border: none;
padding: 12px 18px;
border-radius: 999px;
font-weight: 700;
cursor: pointer;
}
button:hover {
background-color: #1d4ed8;
}
ul {
padding-left: 24px;
margin-top: 20px;
}
li {
font-size: 20px;
margin-bottom: 10px;
}
.message {
margin-top: 16px;
font-size: 18px;
font-weight: 700;
}
</style>
</head>
<body>
<h1>Local Storage</h1>
<div class="card">
<label for="taskInput">Nuova attività</label>
<input id="taskInput" type="text" placeholder="Scrivi un’attività">
<button id="addTaskButton">Aggiungi Attività</button>
<button id="clearTasksButton">Cancella Attività</button>
<p id="message" class="message">Le attività appariranno qui sotto.</p>
<ul id="taskList"></ul>
</div>
<script src="script.js"></script>
</body>
</html>
Ora aggiorna script.js:
const taskInput = document.getElementById("taskInput");
const addTaskButton = document.getElementById("addTaskButton");
const clearTasksButton = document.getElementById("clearTasksButton");
const taskListElement = document.getElementById("taskList");
const messageElement = document.getElementById("message");
let tasks = [];
function saveTasks() {
localStorage.setItem("tasks", JSON.stringify(tasks));
}
function loadTasks() {
const savedTasks = localStorage.getItem("tasks");
if (savedTasks !== null) {
tasks = JSON.parse(savedTasks);
}
}
function showTasks() {
taskListElement.innerHTML = "";
for (const task of tasks) {
const listItem = document.createElement("li");
listItem.textContent = task;
taskListElement.appendChild(listItem);
}
if (tasks.length === 0) {
messageElement.textContent = "Nessuna attività.";
} else {
messageElement.textContent = `Hai ${tasks.length} attività.`;
}
}
function addTask() {
const task = taskInput.value.trim();
if (task === "") {
messageElement.textContent = "Scrivi prima un’attività.";
return;
}
tasks.push(task);
saveTasks();
showTasks();
taskInput.value = "";
}
function clearTasks() {
tasks = [];
saveTasks();
showTasks();
}
addTaskButton.addEventListener("click", addTask);
clearTasksButton.addEventListener("click", clearTasks);
loadTasks();
showTasks();
Ora prova.
Aggiungi un’attività.
Aggiorna la pagina.
L’attività resta.
Aggiungine un’altra.
Aggiorna di nuovo.
È ancora lì.
Complimenti.
Hai costruito una piccola app persistente.
Niente backend.
Niente database.
Solo local storage.
Piccola magia frontend.
Molto soddisfacente.
Come Funziona Questo Codice
Questo array salva le attività in JavaScript:
let tasks = [];
Questo salva le attività in local storage:
function saveTasks() {
localStorage.setItem("tasks", JSON.stringify(tasks));
}
Questo carica le attività da local storage:
function loadTasks() {
const savedTasks = localStorage.getItem("tasks");
if (savedTasks !== null) {
tasks = JSON.parse(savedTasks);
}
}
Questo mostra le attività sulla pagina:
function showTasks() {
taskListElement.innerHTML = "";
for (const task of tasks) {
const listItem = document.createElement("li");
listItem.textContent = task;
taskListElement.appendChild(listItem);
}
}
Questo aggiunge un’attività:
tasks.push(task);
saveTasks();
showTasks();
Schema importante:
Aggiorna dati.
Salva dati.
Mostra dati.
Questo schema appare ovunque.
Anche in app più grandi.
Solo con più file.
Più framework.
E più danni emotivi.
Errori Comuni
Dimenticare JSON.stringify
Sbagliato:
localStorage.setItem("tasks", tasks);
Corretto:
localStorage.setItem("tasks", JSON.stringify(tasks));
Array e oggetti devono essere convertiti in stringhe prima di essere salvati.
Altrimenti JavaScript diventa strano.
Più strano del solito.
Dimenticare JSON.parse
Sbagliato:
const tasks = localStorage.getItem("tasks");
Corretto:
const tasks = JSON.parse(localStorage.getItem("tasks"));
Se hai salvato JSON, fai parse quando leggi.
Stringify quando salvi.
Parse quando carichi.
Come preparare e disfare una valigia.
Provare a Salvare Dati Sensibili
Idea sbagliata:
localStorage.setItem("password", password);
Non farlo.
Le password non appartengono a local storage.
Local storage non è una cassaforte.
È più come un cassetto nella tua stanza.
Utile.
Ma non il posto dove metti lingotti d’oro.
Dimenticare di Aggiornare la Pagina Dopo il Salvataggio
Se salvi solo l’attività:
tasks.push(task);
saveTasks();
ma non chiami:
showTasks();
i dati sono salvati, ma la pagina non si aggiorna.
Il browser non legge la mente.
Digli cosa mostrare.
Pratica
Crea una piccola pagina che salva un colore preferito.
La pagina deve avere:
- un input;
- un pulsante salva;
- un pulsante carica;
- un’area messaggio.
Quando l’utente salva un colore, salvalo in local storage.
Quando lo carica, mostra:
Il tuo colore preferito è blue.
Bonus:
Cambia lo sfondo della pagina con quel colore.
Attenzione ai colori.
Se l’utente scrive “pizza”, il browser potrebbe non capire.
Anche se spiritualmente, pizza è sempre una scelta valida.
Mini Challenge
Crea una piccola app di note.
La pagina deve avere:
- una textarea;
- un pulsante salva;
- un pulsante carica;
- un pulsante cancella.
Regole:
- salva la nota in local storage;
- carica la nota dopo il refresh;
- cancella la nota quando l’utente clicca cancella;
- mostra un messaggio dopo ogni azione.
Questa è una sfida molto pratica.
Molte app reali iniziano con questa idea:
L’utente scrive qualcosa.
L’app lo salva.
L’utente torna più tardi.
I dati sono ancora lì.
Semplice.
Utile.
Potente.
Riepilogo
Oggi hai imparato:
- local storage salva dati nel browser;
- i dati sopravvivono al refresh;
localStorage.setItemsalva dati;localStorage.getItemlegge dati;localStorage.removeItemrimuove un elemento;localStorage.clearrimuove tutto;- local storage salva stringhe;
- i numeri possono richiedere conversione;
- oggetti e array richiedono
JSON.stringify; - JSON salvato richiede
JSON.parse; - local storage è utile per dati semplici;
- local storage non è per password o segreti.
Questo è un grande passo.
Le tue pagine ora possono ricordare cose.
Piccole cose.
Cose utili.
Cose da browser.
JavaScript ha ottenuto una piccola memoria.
Molto utile.
Molto pericolosa se usata male.
Come dare un taccuino a un procione.
Prossima Lezione
Nella prossima lezione impareremo la Fetch API.
Fetch permette a JavaScript di ottenere dati da altri posti.
API.
Server.
File JSON.
Dati reali dal mondo esterno.
Finora la maggior parte dei dati viveva dentro il nostro codice.
Presto JavaScript inizierà a parlare con internet.
Con cautela.
Si spera.