---
title: "Depolama API'leri"
source: 'https://academia.sh/tr/kurslar/tarayici-platformu/depolama-apileri'
course: 'Tarayıcı ve Web Platformu'
language: tr
updated: '2026-08-17T18:09:11+00:00'
license: 'CC BY-SA 4.0'
---

# Depolama API'leri

Sayfa ömrünü aşan veriyi tutan katmanlar; oturum ve kaynak ömrü ayrımı, dizgi deposunun tip ve serileştirme kayıpları, kota ve tahliye, sekmeler arası bildirim, şema göçü ve depolanmaması gereken veri.

Önceki ders formun bir gönderimle bittiğini varsaydı. Çoğu form yarım kalır: kullanıcı
ölçüm değerini girer, sekmeyi kapatır, ertesi gün geri döner. Sayfa yeniden yüklendiğinde
bellekteki her şey silinmiştir — süzgeç alanına yazılan ölçüt de, yarım kalan form da.

Bunları saklamak, tarayıcının sayfa ömrünü aşan bir yere yazmayı gerektirir. Böyle birden
çok yer vardır ve aralarındaki fark boyut değil **ömür, erişim biçimi ve sunucuya
görünürlüktür**.

## Katmanlar

**Oturum depolama (session storage)** sekme ömrüyle sınırlıdır. Aynı adres iki sekmede
açıldığında iki ayrı depo görülür; sekme kapandığında içerik silinir. Yarım kalan bir form
taslağı, çok adımlı bir akışın ara durumu buraya yazılır.

**Yerel depolama (local storage)** kaynak ömrü boyunca kalır. Sekme kapansa da, tarayıcı
kapansa da içerik durur; aynı kaynağın bütün sekmeleri aynı depoyu paylaşır. Kullanıcı
tercihleri, süzgeç ölçütü, son görüntülenen ölçüm buraya yazılır.

**Yapılandırılmış depolama (IndexedDB)** anahtar–değer ikilisinden fazlasını tutar:
dizinlenmiş kayıtlar, işlemler, aralık sorguları. Erişimi eşzamansızdır. Çevrimdışı
çalışacak bir ölçüm günlüğü bu katmanda durur.

**Çerez (cookie)** diğerlerinden farklı bir amaca hizmet eder: İnternet Nasıl Çalışır
kursunda tanımlandığı gibi her istekle sunucuya gider. Bu, oturum kimliği için istenen
davranıştır; arayüz durumu için istenmeyen bir yüktür. Yalnız istemcide kalacak veri
çerezde tutulmaz.

Dördünün ortak sınırı **kaynaktır (origin)**. Şema, ana bilgisayar ve bağlantı noktasının
oluşturduğu üçlü ayrıysa depo da ayrıdır; aynı sunucuda barınan iki farklı kaynak
birbirinin verisini göremez. Çerezin sınırı ayrıca alan adı ve yol bileşenleriyle
daraltılabilir.

## Dizgi Deposunun Davranışı

İlk iki katman yalnızca dizgi tutar. Bu tek cümle üç ayrı sonuç doğurur.

```js
// depo.mjs — dizgi tabanli anahtar-deger deposunun uc davranisi
class Depo {
  constructor(kota) { this.kota = kota; this.kayit = new Map(); }
  get doluluk() {
    let t = 0;
    for (const [a, d] of this.kayit) t += a.length + d.length;
    return t;
  }
  yaz(anahtar, deger) {
    const metin = String(deger);              // her deger dizgiye cevrilir
    const eski = this.kayit.get(anahtar)?.length ?? 0;
    if (this.doluluk - eski + anahtar.length + metin.length > this.kota)
      throw new Error("KotaAsildi");
    this.kayit.set(anahtar, metin);
  }
  oku(anahtar) { return this.kayit.get(anahtar) ?? null; }
}

const depo = new Depo(100);  // kota, kod birimi sayisiyla olculuyor

// 1. Tip kaybi: yazilan sayi, okunan dizgidir.
depo.yaz("esik", 12.5);
console.log("okunan:", JSON.stringify(depo.oku("esik")), "tip:", typeof depo.oku("esik"));
console.log("olmayan anahtar:", depo.oku("yok"));

// 2. Serilestirme kaybi: JSON turu koruyan bir bicim degildir.
const olcum = { kod: "T-01", an: new Date("2024-02-11T06:00:00Z"), not: undefined,
                etiketler: new Set(["gece"]) };
depo.yaz("olcum", JSON.stringify(olcum));
const geri = JSON.parse(depo.oku("olcum"));
console.log("yazilan:", { an: olcum.an.constructor.name, not: olcum.not, etiketler: olcum.etiketler });
console.log("okunan :", geri);

// 3. Kota: yazma islemi hata atar, sessizce basarisiz olmaz.
try {
  depo.yaz("gunluk", "x".repeat(200));
} catch (hata) {
  console.log("hata:", hata.message, "| doluluk:", depo.doluluk, "/", depo.kota);
}
console.log("kota asildiktan sonra 'esik':", JSON.stringify(depo.oku("esik")));
```

```
okunan: "12.5" tip: string
olmayan anahtar: null
yazilan: { an: 'Date', not: undefined, etiketler: Set(1) { 'gece' } }
okunan : { kod: 'T-01', an: '2024-02-11T06:00:00.000Z', etiketler: {} }
hata: KotaAsildi | doluluk: 74 / 100
kota asildiktan sonra 'esik': "12.5"
```

**Tip kaybı.** Yazılan sayı okunurken dizgidir. Karşılaştırmayı dönüştürmeden yapan kod
sessizce yanlış çalışır. Bulunmayan anahtar ise boş dizgi değil boş değer döndürür; ikisi
ayırt edilmelidir, çünkü kullanıcı bir alanı bilerek boş bırakmış olabilir.

**Serileştirme (serialization) kaybı.** JSON, tipleri koruyan bir biçim değildir. Tarih nesnesi dizgiye
döner, tanımsız alan tümüyle düşer, küme boş nesneye dönüşür. Okuma tarafı yalnızca
`JSON.parse` çağırmakla yetinemez; kaydı beklenen tiplere geri çeviren bir katman gerekir.
Tarayıcının iş parçacıkları arasında veri taşırken JSON yerine ayrı bir kopyalama düzeneği
kullanmasının nedeni de budur; o düzenek Web İşçileri dersinde ele alınır.

**Kota.** Depo sınırsız değildir ve sınır aşıldığında yazma **hata atar**. Kotanın büyüklüğü
gerçekleştirime bağlıdır; yazılan kodun buna bir sayı varsayarak değil, hatayı yakalayarak
uyum sağlaması gerekir. Çıktının son satırı ikinci bir kuralı gösterir: başarısız yazma
önceki kaydı bozmaz. Yazma yolu bu nedenle her zaman bir yakalama bloğu içinde durur ve
başarısızlıkta kullanıcıya görünür bir davranış üretir.

Kotayı aşmadan da veri kaybolabilir. Tarayıcı, yer daraldığında ya da veri uzun süre
kullanılmadığında bir kaynağın depolamasını **tahliye** edebilir. Kullanıcı da depolamayı
temizleyebilir. Bu nedenle depolama bir önbellek gibi ele alınır: içeriği olmadan da
çalışan bir sayfa doğru tasarlanmıştır.

## Sekmeler Arası Bildirim

Yerel depolama aynı kaynağın bütün sekmelerince paylaşıldığı için bir sekmedeki yazma
diğerlerini ilgilendirir. Tarayıcı bunun için bir olay üretir; olay eski değeri, yeni
değeri ve anahtarı taşır. Böylece bir sekmede değiştirilen süzgeç ölçütü diğer sekmede de
uygulanabilir.

Bu olayın iki özelliği şaşırtıcıdır. Birincisi, **yazan sekmede üretilmez**; yalnızca diğer
sekmeler bildirim alır. Yazan sekmenin kendi arayüzünü güncellemesi kendi sorumluluğudur.
İkincisi, oturum depolamada bu bildirim anlamsızdır, çünkü depo zaten sekmeye özeldir.

## Eşzamanlılık Maliyeti

İlk iki katmanın erişimi **eşzamanlıdır**: okuma ve yazma, çağrıldığı anda tamamlanır ve
ana iş parçacığı bu sırada başka iş yapamaz. Küçük değerlerde bu görünmez. Büyük bir
kaydı her tuş vuruşunda yazan kod ise kullanıcı arayüzünü bekletir; Olay Modeli dersinde
anılan kuyruk gecikmesi burada da işler.

Üç kural bu maliyeti sınırlar. Yazma seyrekleştirilir — Form Olayları dersindeki gecikmeli
tetikleme burada da geçerlidir. Büyük veri yapılandırılmış depolamaya taşınır; onun
eşzamansız arayüzü ana iş parçacığını bekletmez. Okuma, sayfa açılışında bir kez yapılıp
bellekte tutulur; her erişimde yeniden okunmaz.

## Şema Değişimi

Depolanan veri, onu yazan koddan daha uzun yaşar. Kullanıcının tarayıcısında altı ay
önceki biçimle yazılmış bir kayıt durabilir. Bu nedenle her kayıt bir **sürüm** alanı
taşır ve okuma yolu, eski sürümü güncel biçime taşıyan bir zincir içerir.

```js
// goc.mjs — depodaki kaydin surumlenmesi ve ileri goc
const GUNCEL = 3;
const GOC = {
  1: (k) => ({ ...k, birim: "C" }),                                   // 1 -> 2: birim eklendi
  2: ({ deger, ...k }) => ({ ...k, sicaklik: Number(deger) }),        // 2 -> 3: alan adi ve tipi
};

function oku(ham) {
  let kayit;
  try { kayit = JSON.parse(ham); }
  catch { return { sonuc: "cozumlenemedi", kayit: null }; }

  const surum = kayit.surum ?? 1;
  if (surum > GUNCEL) return { sonuc: "gelecek surum, yok sayildi", kayit: null };

  let s = surum;
  while (s < GUNCEL) { kayit = { ...GOC[s](kayit), surum: s + 1 }; s += 1; }
  return { sonuc: `surum ${surum} -> ${GUNCEL}`, kayit };
}

const ornekler = [
  '{"kod":"T-01","deger":"-4.2"}',                                  // surum alani yok: 1 sayilir
  '{"surum":2,"kod":"T-02","deger":"3.5","birim":"C"}',
  '{"surum":3,"kod":"T-03","sicaklik":11.8,"birim":"C"}',
  '{"surum":9,"kod":"T-04"}',
  '{kod:"T-05"}',
];

for (const ham of ornekler) {
  const { sonuc, kayit } = oku(ham);
  console.log(sonuc.padEnd(26), JSON.stringify(kayit));
}
```

```
surum 1 -> 3               {"kod":"T-01","birim":"C","surum":3,"sicaklik":-4.2}
surum 2 -> 3               {"surum":3,"kod":"T-02","birim":"C","sicaklik":3.5}
surum 3 -> 3               {"surum":3,"kod":"T-03","sicaklik":11.8,"birim":"C"}
gelecek surum, yok sayildi null
cozumlenemedi              null
```

Zincir dört durumu birden karşılar. Sürüm alanı olmayan en eski kayıt birinci sürüm
sayılır ve iki adımda güncel biçime taşınır. Ara sürüm kalan adımı atlar. Güncel kayıt
dokunulmadan geçer.

Son iki satır savunma tarafıdır. **Gelecekten gelen** bir kayıt — kullanıcının başka bir
cihazdan eşitlediği ya da daha yeni bir sürümle yazılmış olan — geriye taşınamaz; okunmaz
ve yok sayılır. **Çözümlenemeyen** içerik de aynı biçimde ele alınır. Depodan okunan her
şey dış girdidir: bozuk olabilir, elle değiştirilmiş olabilir, hiç yazılmamış olabilir.
Çözümleme her zaman bir yakalama bloğu içinde yapılır.

## Ne Saklanmaz

Depolama, kullanıcının cihazında ve kullanıcının denetiminde duran bir alandır. Buradan üç
kural çıkar.

Sayfada çalışan her kod aynı depoyu okuyabilir; bu nedenle **kimlik belirteci, parola ve
kişisel veri** oraya yazılmaz. Bir betik enjeksiyonu, depodaki her şeye erişir.

Depo **kaydın kaynağı değildir**. Sunucudaki veriye göre ikincildir; çakışma durumunda
hangisinin kazanacağı açıkça kararlaştırılır.

Kullanıcı depoyu her an temizleyebilir ve tarayıcı tahliye edebilir. Bu nedenle depolanan
veri **yeniden üretilebilir** olmalıdır; kaybı bir işlevi kalıcı olarak bozmamalıdır.

## Özet

- Oturum depolama sekme ömrüyle, yerel depolama kaynak ömrüyle sınırlıdır; yapılandırılmış
  depolama dizinli kayıtları eşzamansız arayüzle tutar, çerez ise her istekle sunucuya gider.
- Dizgi depoları yazılan değeri dizgiye çevirir ve JSON tipleri korumaz; okuma tarafı kaydı
  beklenen tiplere geri çeviren bir katman gerektirir.
- Kota aşımı hata atar ve önceki kaydı bozmaz; kotanın büyüklüğü varsayılmaz, hata yakalanır.
- Yerel depolamadaki değişiklik diğer sekmelere olayla bildirilir; yazan sekme bu olayı
  görmez ve kendi arayüzünü kendisi günceller.
- Eşzamanlı erişim ana iş parçacığını bekletir; yazma seyreltilir, büyük veri
  yapılandırılmış depolamaya taşınır, okuma bir kez yapılıp bellekte tutulur.
- Kayıtlar sürüm alanı taşır ve okuma yolunda göç zincirinden geçer; gelecek sürümlü ya da
  çözümlenemeyen içerik yok sayılır.

## Sonraki Adım

Bu ders durumu sakladı ama durumun **adresle** ilişkisine dokunmadı. Süzgeç ölçütü depoda
tutulduğunda sayfa yeniden açıldığında geri gelir; ancak o hâlin bir adresi yoktur.
Kullanıcı süzülmüş listeyi paylaşamaz, yer imine ekleyemez, geri düğmesiyle önceki süzgece
dönemez. Bunlar depolamanın değil gezinmenin sorunlarıdır ve tarayıcının adres çubuğu ile
geçmiş yığıtı üzerinden çözülür. Sonraki ders adresin parçalarını, geçmiş yığıtının nasıl
değiştirildiğini ve istemci tarafı gezinmenin hangi noktada sunucuyla anlaşmak zorunda
olduğunu inceler.
