Tarayıcı depolama, JSON serileştirme ve gerçek dünya kullanımı.
Tarayıcı depolama, kullanıcı verilerini sunucuya göndermeden istemci tarafında saklamayı sağlar. LocalStorage kalıcıdır (tarayıcı kapatılsa bile durur), SessionStorage sekme kapatılınca silinir.
Çoğu tarayıcıda 5-10MB depolama sınırı vardır. Yalnızca string saklanabilir — nesneleri saklamak için JSON.stringify(), okumak için JSON.parse() kullanılmalıdır.
Kullanıcı tercihleri (tema, dil), form taslakları, uygulamanın durumu (sepet, filtreler) için uygundur. Şifre, token, kişisel veri kesinlikle saklanmamalıdır — XSS saldırısıyla çalınabilir. Hassas veriler için Cookie (HttpOnly) veya sunucu taraflı oturum kullanın.
Aynı sitenin başka sekmesinde storage değiştiğinde storage olayı tetiklenir. Bu sayede farklı sekmeler arasında veri senkronizasyonu yapılabilir.
<!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<style>
body { font-family: sans-serif; padding: 20px; max-width: 600px; }
button { padding: 8px 16px; background: #6366f1; color: white; border: none; border-radius: 8px; cursor: pointer; margin: 4px; }
input, select { padding: 8px; border: 1px solid #e2e8f0; border-radius: 8px; font-size: 14px; }
.kart { background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 10px; padding: 16px; margin: 10px 0; }
.silme-btn { background: #ef4444; padding: 4px 10px; font-size: 12px; }
</style>
</head>
<body>
<h2>📦 Depolama Yöneticisi</h2>
<div class="kart">
<h3>Kullanıcı Tercihleri</h3>
<label>Tema: </label>
<select id="tema" onchange="tercihleriKaydet()">
<option value="acik">Açık</option>
<option value="karanlik">Karanlık</option>
</select>
<label> Font: </label>
<select id="font" onchange="tercihleriKaydet()">
<option value="14">14px</option>
<option value="16">16px</option>
<option value="18">18px</option>
</select>
</div>
<div class="kart">
<h3>Not Defteri (LocalStorage)</h3>
<input id="not-input" type="text" placeholder="Not ekle..." style="width:60%">
<button onclick="notEkle()">+ Ekle</button>
<div id="notlar"></div>
</div>
<div class="kart">
<h3>Oturum Sayacı (SessionStorage)</h3>
<p>Bu oturumda <strong id="sayac">0</strong> kez ziyaret ettiniz.</p>
<button onclick="sayaciSifirla()">Sıfırla</button>
</div>
<button onclick="hepsiniTemizle()" style="background:#ef4444">🗑 Tümünü Temizle</button>
<script>
// ── Storage Yardımcı Fonksiyonlar ──
const Storage = {
set(anahtar, deger) {
localStorage.setItem(anahtar, JSON.stringify(deger));
},
get(anahtar, varsayilan = null) {
try {
const veri = localStorage.getItem(anahtar);
return veri ? JSON.parse(veri) : varsayilan;
} catch { return varsayilan; }
},
sil(anahtar) {
localStorage.removeItem(anahtar);
},
temizle() {
localStorage.clear();
}
};
// ── Tercihler ──
function tercihleriKaydet() {
const tercihler = {
tema: document.getElementById('tema').value,
font: document.getElementById('font').value,
kayit_zamani: new Date().toISOString()
};
Storage.set('tercihler', tercihler);
document.body.style.fontSize = tercihler.font + 'px';
console.log('Tercihler kaydedildi:', tercihler);
}
function tercihleriYukle() {
const tercihler = Storage.get('tercihler', { tema: 'acik', font: '14' });
document.getElementById('tema').value = tercihler.tema;
document.getElementById('font').value = tercihler.font;
document.body.style.fontSize = tercihler.font + 'px';
}
// ── Notlar ──
function notEkle() {
const input = document.getElementById('not-input');
const metin = input.value.trim();
if (!metin) return;
const notlar = Storage.get('notlar', []);
notlar.push({ id: Date.now(), metin, tarih: new Date().toLocaleString('tr-TR') });
Storage.set('notlar', notlar);
input.value = '';
notlariGoster();
}
function notSil(id) {
const notlar = Storage.get('notlar', []).filter(n => n.id !== id);
Storage.set('notlar', notlar);
notlariGoster();
}
function notlariGoster() {
const notlar = Storage.get('notlar', []);
const html = notlar.length === 0
? '<p style="color:#94a3b8;font-size:13px">Henüz not yok</p>'
: notlar.map(n => `
<div style="display:flex;justify-content:space-between;align-items:center;padding:8px 0;border-bottom:1px solid #e2e8f0">
<div>
<span>${n.metin}</span>
<small style="color:#94a3b8;margin-left:8px">${n.tarih}</small>
</div>
<button class="silme-btn" onclick="notSil(${n.id})">Sil</button>
</div>
`).join('');
document.getElementById('notlar').innerHTML = html;
}
// ── Session Storage ──
function sayacGuncelle() {
let sayi = parseInt(sessionStorage.getItem('ziyaret') || '0') + 1;
sessionStorage.setItem('ziyaret', sayi);
document.getElementById('sayac').textContent = sayi;
}
function sayaciSifirla() {
sessionStorage.removeItem('ziyaret');
document.getElementById('sayac').textContent = '0';
}
function hepsiniTemizle() {
Storage.temizle();
sessionStorage.clear();
notlariGoster();
tercihleriYukle();
document.getElementById('sayac').textContent = '0';
}
// ── Başlangıç ──
tercihleriYukle();
notlariGoster();
sayacGuncelle();
// Storage değişikliği dinle (başka sekmeden değişince)
window.addEventListener('storage', function(e) {
console.log(`Storage değişti: ${e.key}`, e.oldValue, '→', e.newValue);
if (e.key === 'notlar') notlariGoster();
if (e.key === 'tercihler') tercihleriYukle();
});
</script>
</body>
</html>