Storage — localStorage, sessionStorage, Cookies

Page reload-এর পরও state রাখুন

~25 min Beginner 10 practice problems Live runner

1. Three Storage Mechanisms

APILifetimeSizeSent with HTTP?
localStorageUntil cleared~5 MBNo
sessionStoragePer tab~5 MBNo
cookieUntil expiry~4 KBYes (every request)
IndexedDBUntil clearedHundreds of MBNo
localStorage permanent, sessionStorage শুধু এই tab-এ। Cookie প্রতি HTTP request-এ server-এ যায় (তাই auth-এ ব্যবহৃত)। বড় data হলে IndexedDB।

2. localStorage Basics

localStorage.setItem("theme", "dark");
localStorage.getItem("theme");           // "dark"
localStorage.removeItem("theme");
localStorage.clear();

// Key count + iterate
for (let i = 0; i < localStorage.length; i++) {
    const key = localStorage.key(i);
    console.log(key, localStorage.getItem(key));
}

// Cross-tab sync
addEventListener("storage", e => {
    console.log("changed:", e.key, e.oldValue, "→", e.newValue);
});
Strings only All values are coerced to strings. To store objects, use JSON.stringify on the way in and JSON.parse on the way out. Wrap reads in try/catch — corrupted JSON throws.

3. JSON Helper Pattern

helper.js
// Mock localStorage so the snippet runs in the sandbox
const store = {
    map: {},
    setItem(k, v) { this.map[k] = String(v); },
    getItem(k)    { return this.map[k] ?? null; },
    removeItem(k) { delete this.map[k]; }
};

const save = (k, v) => store.setItem(k, JSON.stringify(v));
const load = (k, fallback = null) => {
    try { return JSON.parse(store.getItem(k)) ?? fallback; }
    catch { return fallback; }
};

save("settings", { theme: "dark", lang: "bn" });
console.log(load("settings"));
console.log(load("missing", { theme: "light" }));

4. Cookies

document.cookie = "lang=bn; Max-Age=86400; Path=/; SameSite=Lax; Secure";
console.log(document.cookie);   // "lang=bn; sid=abc..."

// Cookies are parsed as one big string — write a helper
const getCookie = (name) => {
    return document.cookie.split("; ")
        .find(row => row.startsWith(name + "="))
        ?.split("=")[1];
};
AttributeEffect
PathURL path scope
DomainSubdomain scope
Expires / Max-AgeHow long it lives
SecureHTTPS only
HttpOnlyJS can't read it (set by server)
SameSiteLax / Strict / None — CSRF protection

5. Security — Where to Put a JWT

Don't store tokens in localStorage if XSS is possible localStorage is readable by any script on the page. A single XSS bug exposes the token. The safer pattern: keep the session token in an HttpOnly; Secure; SameSite=Lax cookie set by the server. JS can't read it, but the browser sends it on every request.

6. IndexedDB — Quick Preview

For larger structured data (offline mail, photos, full DBs), use IndexedDB. The native API is verbose; most apps use a wrapper like idb or Dexie.

// Native (sketch)
const req = indexedDB.open("notes-db", 1);
req.onupgradeneeded = e => {
    e.target.result.createObjectStore("notes", { keyPath: "id" });
};
req.onsuccess = e => { /* use e.target.result */ };

7. Glossary (শব্দকোষ)

TermMeaningবাংলায়
localStoragePersistent string-only key-value store (~5 MB).Reload-এর পরও থাকে; string-only; ~5 MB।
sessionStorageSame API but cleared when the tab closes.একই API; tab বন্ধ হলে clear।
CookieSmall key-value sent with every HTTP request to the same site.প্রতি HTTP request-এ server-এ যাওয়া ছোট key-value।
HttpOnlyCookie attribute that hides it from JS — server-only.JS পড়তে পারবে না — শুধু server।
SecureCookie sent only over HTTPS.শুধু HTTPS-এ পাঠায়।
SameSiteCSRF protection — Lax / Strict / None.CSRF protection — Lax/Strict/None।
QuotaPer-origin storage size limit set by the browser.Browser-এর প্রতি origin-এ storage limit।
storage eventFired in other tabs when localStorage changes.localStorage বদলালে অন্য tab-এ fire হয়।
IndexedDBAsync, structured DB for hundreds of MB of data.Async, structured — শত শত MB রাখা যায়।
JWTJSON Web Token — signed token used for auth.Auth-এর signed JSON token।
মনে রাখুন: localStorage permanent, sessionStorage শুধু এই tab-এ। Cookie প্রতি HTTP request-এ server-এ যায় — তাই auth-এর জন্য আদর্শ। Token সবসময় HttpOnly; Secure; SameSite=Lax cookie-তে রাখুন — localStorage-এ XSS হলে token চুরি হয়। বড় data হলে IndexedDB।

8. Practice Problems

  1. Save and read a string in localStorage (sketch).
    ✨ Show Answer
    localStorage.setItem("name", "Arif");
    console.log(localStorage.getItem("name"));
  2. Persist an object using JSON.stringify.
    ✨ Show Answer
    a2.js
    const map = {};
    const set = (k, v) => map[k] = JSON.stringify(v);
    const get = k => JSON.parse(map[k]);
    
    set("u", { name: "Arif", age: 22 });
    console.log(get("u"));
  3. Build a "load with default" helper (sandbox-safe).
    ✨ Show Answer
    a3.js
    const raw = "not-json";
    const load = (s, def) => {
        try { return JSON.parse(s); }
        catch { return def; }
    };
    console.log(load(raw, { ok: false }));
  4. When should you choose sessionStorage over localStorage?
    ✨ Show Answer

    Answer: When state should not survive a tab close — multi-step wizards, draft data, ephemeral filters. Each tab gets its own sessionStorage, so opening the same site in two tabs gives two independent stores.

  5. Parse a cookie string into an object.
    ✨ Show Answer
    a5.js
    const cookie = "lang=bn; theme=dark; sid=abc123";
    const parsed = Object.fromEntries(
        cookie.split("; ").map(s => s.split("=")));
    console.log(parsed);
  6. Why must HttpOnly cookies be set by the server?
    ✨ Show Answer

    Answer: The whole point is that JS can neither read nor write the cookie. Browsers therefore disallow document.cookie = "...; HttpOnly". The server uses a Set-Cookie response header.

  7. Listen for storage events to sync state across tabs (sketch).
    ✨ Show Answer
    addEventListener("storage", e => {
        if (e.key === "theme") applyTheme(e.newValue);
    });
  8. Why is localStorage limited to ~5 MB?
    ✨ Show Answer

    Answer: The web platform reserves localStorage for small, frequently-read settings. Quotas vary by browser (5 MB is typical). For larger data — files, images, full datasets — use IndexedDB which has hundreds of MB and async access (so it doesn't block the main thread).

  9. Implement a tiny "preferences" wrapper with .get/.set.
    ✨ Show Answer
    a9.js
    const prefs = (() => {
        const store = {};
        return {
            get(k, def) {
                try { return store[k] != null ? JSON.parse(store[k]) : def; }
                catch { return def; }
            },
            set(k, v) { store[k] = JSON.stringify(v); }
        };
    })();
    
    prefs.set("theme", "dark");
    console.log(prefs.get("theme", "light"));
    console.log(prefs.get("missing", "default"));
  10. In one paragraph, explain when to choose cookies over localStorage.
    ✨ Show Answer

    Answer: Use cookies when the server needs the value automatically — most importantly for authentication, where an HttpOnly; Secure; SameSite cookie is the safest place for a session ID. Use localStorage for client-only state (theme, draft, last-opened tab) where there's no benefit to shipping the value over the wire.

Summary — Module 28

localStorage persists across reloads; sessionStorage dies with the tab; cookies travel with every HTTP request. Always JSON-encode complex values for storage. Tokens belong in HttpOnly cookies, not localStorage. Big data → IndexedDB.

localStorage permanent, sessionStorage tab-only, cookie server-bound। Token HttpOnly cookie-তে রাখুন; বড় data IndexedDB-তে।

Next Module → Web APIs — Geolocation, Notifications, Workers।