localStorage ve sessionStorage’a Giriş: Web Tarayıcısında Veri Depolama Mekanizmaları
Web uygulamaları, kullanıcı deneyimini zenginleştirmek ve performansı artırmak amacıyla sıklıkla istemci tarafında veri depolama ihtiyacı duyar. Kullanıcı tercihleri, oturum bilgileri, çevrimdışı önbellekler veya geçici veriler gibi çeşitli bilgilerin tarayıcıda saklanması, hem sunucu yükünü azaltır hem de daha hızlı ve kişiselleştirilmiş bir deneyim sunar. Geleneksel olarak bu tür ihtiyaçlar için çerezler (cookies) kullanılırdı, ancak çerezlerin birtakım sınırlamaları modern web uygulamalarının beklentilerini karşılamakta yetersiz kalmıştır. Bu noktada, Web Storage API’si devreye girerek, localStorage ve sessionStorage adını verdiğimiz iki güçlü ve esnek mekanizma sunmuştur.
Bu makalede, localStorage ve sessionStorage‘ın ne olduğunu, nasıl çalıştığını, temel kullanım senaryolarını, metodlarını, aralarındaki farkları, güvenlik hususlarını ve en iyi uygulamalarını detaylı bir şekilde inceleyeceğiz. Ayrıca, Web Storage API’sinin çerezlere göre avantajlarını ve diğer istemci tarafı depolama seçeneklerine kıyasla konumunu da ele alacağız. Amacımız, geliştiricilere bu iki güçlü aracın potansiyelini tam olarak anlama ve projelerinde etkin bir şekilde kullanma konusunda kapsamlı bir rehber sunmaktır.
Cookies’den Web Storage’a: Neden Bir Değişime İhtiyaç Duyuldu?
Web’in ilk yıllarından itibaren, istemci tarafında veri depolama ihtiyacı doğduğunda akla gelen ilk çözüm çerezler (cookies) olmuştur. Çerezler, sunucunun kullanıcı tarayıcısına küçük metin dosyaları göndermesine ve bu dosyaların daha sonra aynı sunucuya yapılan her HTTP isteğiyle birlikte geri gönderilmesine olanak tanır. Oturum yönetimi, kullanıcı takibi ve kişiselleştirme gibi birçok temel işlevde çerezler önemli bir rol oynamıştır. Ancak, modern web uygulamalarının artan karmaşıklığı ve veri depolama gereksinimleri, çerezlerin bazı temel sınırlamalarını ortaya çıkarmıştır:
* Boyut Sınırlaması: Çerezler genellikle 4 KB ile sınırlıdır. Bu, büyük miktarda veri depolamak için yetersizdir ve geliştiricileri verileri parçalamaya veya başka çözümler aramaya iter.
* Performans Yükü: Çerezler, her HTTP isteğiyle (görseller, CSS, JavaScript dosyaları dahil) otomatik olarak sunucuya gönderilir. Bu durum, gereksiz ağ trafiği oluşturarak performansı olumsuz etkileyebilir, özellikle mobil ağlarda veya yüksek gecikmeli bağlantılarda.
* Güvenlik Riskleri: Çerezler, HttpOnly bayrağı ile korunmadıkça JavaScript tarafından erişilebilir durumdadır. Bu, siteler arası komut çalıştırma (XSS) saldırılarında hassas bilgilerin çalınması riskini doğurur. Ayrıca, her istekle gönderilmeleri, man-in-the-middle saldırılarında da risk oluşturabilir.
* Karmaşık API: Çerezler, doğrudan anahtar-değer çiftleri olarak depolansa da, okunmaları ve yazılmaları document.cookie dizesini manuel olarak ayrıştırmayı veya manipüle etmeyi gerektirir, bu da kod yazımını karmaşıklaştırır.
* Süre Sonu Yönetimi: Çerezlerin bir süre sonu (expiration) değeri vardır ve bu değerin doğru bir şekilde yönetilmesi gerekir. Süresi dolan çerezler otomatik olarak silinir.
Bu sınırlamalar, web geliştiricilerini daha modern, daha kapasiteli ve daha kullanımı kolay istemci tarafı depolama çözümlerine yönlendirmiştir. İşte bu noktada Web Storage API’si, özellikle localStorage ve sessionStorage, çerezlerin yerini alabilecek veya onları tamamlayabilecek güçlü alternatifler olarak ortaya çıkmıştır. Web Storage, daha büyük depolama kapasitesi, daha basit bir API ve sunucuya gönderilmeme avantajlarıyla modern web uygulamalarının ihtiyaçlarına çok daha iyi yanıt vermektedir.
Web Storage API Nedir?
Web Storage API’si, HTML5 ile birlikte tanıtılan ve web uygulamalarının istemci tarafında, yani kullanıcının tarayıcısında veri depolamasına olanak tanıyan bir dizi araçtır. Bu API, localStorage ve sessionStorage olmak üzere iki ana nesne üzerinden çalışır. Her ikisi de anahtar-değer çiftleri (key-value pairs) şeklinde veri depolama prensibine dayanır ve JavaScript aracılığıyla kolayca erişilebilir ve yönetilebilir.
Web Storage’ın temel özellikleri şunlardır:
* Basit Anahtar-Değer Depolama: Veriler, benzersiz bir anahtar ile ilişkilendirilmiş bir değer olarak saklanır. Hem anahtar hem de değer her zaman birer dize (string) olmalıdır. Eğer bir JavaScript nesnesi veya dizisi depolamak isterseniz, JSON.stringify() kullanarak dizeye dönüştürmeniz, alırken de JSON.parse() kullanarak orijinal haline getirmeniz gerekir.
* Daha Büyük Kapasite: Çerezlerin 4 KB’lık sınırlamasının aksine, Web Storage genellikle tarayıcıya ve cihaza bağlı olarak 5 MB ila 10 MB arasında bir depolama alanı sunar. Bu, daha büyük miktarda verinin istemci tarafında saklanabilmesi anlamına gelir.
* İstemci Tarafı Depolama: Web Storage’da depolanan veriler, HTTP istekleriyle sunucuya gönderilmez. Bu, hem ağ trafiğini azaltır hem de performansı artırır. Verilere yalnızca istemci tarafındaki JavaScript kodu erişebilir.
* Origin (Domain) Bazlı Güvenlik: Her iki depolama türü de aynı köken politikasına (Same-Origin Policy) tabidir. Bu, bir web sitesinin yalnızca kendi kökeninden (protokol, alan adı ve port kombinasyonu) depoladığı verilere erişebileceği anlamına gelir. Farklı bir kökene sahip siteler, birbirlerinin depoladığı verilere doğrudan erişemez.
* Senkron Çalışma: Web Storage işlemleri (veri yazma, okuma, silme) senkrondur. Bu, işlem tamamlanana kadar ana iş parçacığının (main thread) bloke olabileceği anlamına gelir. Küçük veriler için genellikle sorun teşkil etmese de, çok büyük verilerle çalışırken dikkatli olunmalıdır.
Web Storage API’si, window.localStorage ve window.sessionStorage global nesneleri aracılığıyla erişilebilir. Bu nesneler, verileri yönetmek için aynı metod setine sahiptir. Aralarındaki temel fark, verinin kalıcılığı ve kapsamıdır.
localStorage Detaylı İnceleme
localStorage nesnesi, web uygulamalarının tarayıcıda kalıcı olarak veri depolamasını sağlayan bir Web Storage mekanizmasıdır. “Kalıcı” kelimesi burada anahtar bir role sahiptir; çünkü localStorage‘a kaydedilen veriler, tarayıcı kapatılıp açılsa bile, hatta bilgisayar yeniden başlatılsa bile kaybolmaz. Veriler, kullanıcı veya web uygulaması tarafından açıkça silinene kadar tarayıcıda saklanmaya devam eder.
Kalıcı Veri Depolama
localStorage‘ın en belirgin özelliği, verilerin kalıcılığıdır. Bir kullanıcı bir web sitesini ziyaret ettiğinde ve bu site localStorage‘a veri yazdığında, bu veriler tarayıcının yerel depolama alanında saklanır. Kullanıcı tarayıcı sekmesini kapatsa, tarayıcıyı tamamen kapatsa veya bilgisayarını yeniden başlatsa bile, aynı kökenden (domain) siteyi tekrar ziyaret ettiğinde bu verilere erişebilir. Veriler ancak aşağıdaki durumlarda silinir:
* Web uygulaması, JavaScript kodu aracılığıyla veriyi açıkça siler (removeItem() veya clear()).
* Kullanıcı, tarayıcısının ayarlarından site verilerini veya tüm tarayıcı geçmişini/önbelleğini temizler.
* Tarayıcı veya işletim sistemi düzeyinde bir sorun oluşur (nadiren).
Bu kalıcılık, localStorage‘ı belirli kullanım senaryoları için vazgeçilmez kılar.
Kullanım Senaryoları
localStorage, genellikle uzun süreli veya kalıcı olması beklenen kullanıcıya özel verileri depolamak için kullanılır:
* Kullanıcı Tercihleri: Tema seçimi (açık/koyu mod), dil tercihleri, yazı tipi boyutu, bildirim ayarları gibi kişiselleştirme seçenekleri.
* Çevrimdışı Veri Depolama/Önbellekleme: Bir uygulamanın çevrimdışı çalışabilmesi için gerekli olan statik kaynaklar, sıkça erişilen veriler veya kullanıcının oluşturduğu taslaklar (örneğin, bir blog gönderisi taslağı).
* Alışveriş Sepeti İçeriği: Kullanıcı henüz giriş yapmamış olsa bile, alışveriş sepetine eklediği ürünlerin bilgilerini kalıcı olarak saklamak.
* Kullanıcı Kimlik Doğrulama Tokenları: JWT (JSON Web Token) gibi kimlik doğrulama tokenları, kullanıcının oturumunu sürdürmek için localStorage‘da saklanabilir (ancak güvenlik riskleri nedeniyle bu konuda dikkatli olunmalıdır).
* Performans Optimizasyonu: Sunucudan sıkça çekilen ancak sık değişmeyen verileri (örneğin, bir ürün kataloğu veya statik içerik) önbelleğe almak, sonraki yüklemelerde daha hızlı erişim sağlar.
Temel Metotlar
localStorage nesnesi, verileri yönetmek için basit ve sezgisel bir API sunar:
* localStorage.setItem(key, value): Belirtilen anahtar (key) ile değeri (value) localStorage‘a kaydeder. Hem anahtar hem de değer dize (string) olmalıdır. Eğer anahtar zaten varsa, değeri güncellenir.
* localStorage.getItem(key): Belirtilen anahtara karşılık gelen değeri döndürür. Eğer anahtar bulunamazsa null döndürür.
* localStorage.removeItem(key): Belirtilen anahtara sahip öğeyi localStorage‘dan siler.
* localStorage.clear(): localStorage‘daki tüm öğeleri siler. Bu işlem geri alınamaz.
* localStorage.key(index): Belirtilen dizindeki (0’dan başlayarak) anahtarın adını döndürür.
* localStorage.length: localStorage‘daki depolanmış öğelerin sayısını döndürür.
Örnek Kullanım
Aşağıdaki JavaScript kod örnekleri, localStorage‘ın temel metotlarını göstermektedir:
// 1. Veri Kaydetme (setItem)
// Not: Sadece string depolayabiliriz. Nesneleri JSON.stringify ile dönüştürmeliyiz.
localStorage.setItem('kullaniciAdi', 'Alice');
localStorage.setItem('temaTercihi', 'dark');
const kullaniciAyarlari = {
dil: 'tr',
bildirimlerAcik: true,
sonGiris: new Date()
};
localStorage.setItem('ayarlar', JSON.stringify(kullaniciAyarlari));
console.log('Veriler kaydedildi.');
// 2. Veri Okuma (getItem)
const kaydedilenKullaniciAdi = localStorage.getItem('kullaniciAdi');
console.log('Kaydedilen kullanıcı adı:', kaydedilenKullaniciAdi); // Çıktı: Alice
const kaydedilenTema = localStorage.getItem('temaTercihi');
console.log('Kaydedilen tema tercihi:', kaydedilenTema); // Çıktı: dark
const kaydedilenAyarlarJSON = localStorage.getItem('ayarlar');
if (kaydedilenAyarlarJSON) {
const ayarlarObjesi = JSON.parse(kaydedilenAyarlarJSON);
console.log('Kaydedilen ayarlar:', ayarlarObjesi);
console.log('Dil ayarı:', ayarlarObjesi.dil); // Çıktı: tr
}
// 3. Veri Silme (removeItem)
localStorage.removeItem('temaTercihi');
console.log('Tema tercihi silindi.');
const temaTekrarKontrol = localStorage.getItem('temaTercihi');
console.log('Tema tercihi (silindikten sonra):', temaTekrarKontrol); // Çıktı: null
// 4. Tüm Verileri Silme (clear)
// Dikkat: Bu işlem tüm localStorage verilerini siler!
// localStorage.clear();
// console.log('Tüm localStorage verileri silindi.');
// 5. Anahtar Adına ve Uzunluğuna Erişim
console.log('Depolanan öğe sayısı:', localStorage.length); // Öğe sayısını gösterir
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
const value = localStorage.getItem(key);
console.log(Anahtar: ${key}, Değer: ${value});
}
Sınırlamalar ve Dikkat Edilmesi Gerekenler
localStorage güçlü bir araç olsa da, kullanırken göz önünde bulundurulması gereken bazı sınırlamaları ve güvenlik endişeleri vardır:
* Sadece String Depolama: localStorage sadece dize (string) türündeki verileri depolayabilir. Nesneler, diziler, sayılar veya boolean değerler gibi diğer veri türlerini depolamak için JSON.stringify() ile dizeye dönüştürmeniz ve alırken JSON.parse() ile tekrar dönüştürmeniz gerekir.
* Senkron Çalışma: Tüm localStorage işlemleri senkrondur. Bu, özellikle büyük veri kümeleriyle çalışırken ana iş parçacığını bloke edebilir ve uygulamanın kullanıcı arayüzünü (UI) geçici olarak dondurabilir. Bu tür senaryolar için IndexedDB gibi asenkron çözümler daha uygun olabilir.
* Güvenlik Endişeleri (XSS): localStorage‘da depolanan verilere JavaScript aracılığıyla kolayca erişilebilir. Eğer web siteniz bir siteler arası komut çalıştırma (XSS) saldırısına maruz kalırsa, kötü niyetli kod localStorage‘daki tüm verilere erişebilir ve bunları çalabilir. Bu nedenle, localStorage‘da asla hassas bilgiler (şifreler, kredi kartı numaraları, kişisel kimlik bilgileri) saklanmamalıdır. Kimlik doğrulama tokenları gibi veriler depolanacaksa, bu tokenların kısa ömürlü olması ve sunucu tarafında doğrulanması gibi ek güvenlik önlemleri alınmalıdır.
* Veri Bütünlüğü: localStorage‘daki veriler istemci tarafında depolandığı için kullanıcı tarafından kolayca değiştirilebilir. Bu nedenle, uygulamanızın kritik mantığını localStorage‘daki verilere tamamen dayandırmamalısınız. Sunucu tarafında her zaman veri doğrulaması yapılmalıdır.
* Depolama Limitleri: Tarayıcıya göre değişmekle birlikte, genellikle 5-10 MB gibi bir depolama limiti vardır. Bu limit aşıldığında tarayıcı bir hata fırlatabilir.
* Veri Şifreleme Yok: localStorage verileri varsayılan olarak şifrelenmez. Tarayıcıda düz metin olarak saklanır. Bu da hassas veriler için büyük bir risk oluşturur.
sessionStorage Detaylı İnceleme
sessionStorage nesnesi, localStorage‘a benzer şekilde anahtar-değer çiftleri halinde veri depolayan bir Web Storage mekanizmasıdır. Ancak, sessionStorage‘ın temel farkı, verilerin kalıcılığı ve kapsamıdır. sessionStorage‘a kaydedilen veriler, sadece o tarayıcı oturumu boyunca geçerlidir.
Oturum Bazlı Veri Depolama
sessionStorage‘ın en belirgin özelliği, verilerin “oturum bazlı” olmasıdır. Bir oturum, bir tarayıcı sekmesinin veya penceresinin açık kaldığı süre boyunca devam eder.
* Sekme/Pencere Kapatıldığında Veri Kaybı: Bir tarayıcı sekmesi veya penceresi kapatıldığında, o sekmenin sessionStorage‘ında depolanan tüm veriler otomatik olarak silinir.
* Yeni Sekme/Pencere = Yeni Oturum: Aynı web sitesini farklı bir tarayıcı sekmesinde veya penceresinde açtığınızda, bu yeni sekme/pencere tamamen bağımsız bir sessionStorage oturumu başlatır. Yani, bir sekmede depolanan veriler, diğer bir sekmede otomatik olarak erişilemez.
* Yenileme Kalıcılığı: Sayfa yenilendiğinde (F5 veya tarayıcının yenileme düğmesi), sessionStorage‘daki veriler korunur. Bu, kullanıcının o anki oturumdaki durumunu sürdürmek için faydalıdır.
* Tarayıcı Kapatıldığında Veri Kaybı: Tarayıcının tamamı kapatıldığında, tüm sessionStorage verileri silinir.
Bu oturum bazlı doğa, sessionStorage‘ı geçici veya oturuma özel verileri depolamak için ideal kılar.
Kullanım Senaryoları
sessionStorage, genellikle bir kullanıcının tek bir oturum içindeki belirli bir görevi veya yolculuğu sırasında ihtiyaç duyulan geçici verileri depolamak için kullanılır:
* Çok Adımlı Formlar: Bir kullanıcının bir formu doldururken adımlar arasında geçiş yaparken girdiği verileri geçici olarak saklamak. Örneğin, ödeme veya kayıt formları.
* Geçici Kullanıcı Girişleri: Bir kullanıcının bir oturum boyunca yaptığı belirli seçimleri veya girişleri (örneğin, filtre seçenekleri, sıralama tercihleri) saklamak.
* Tek Oturumluk Alışveriş Sepeti: Kullanıcının sadece o oturum için geçerli olacak bir alışveriş sepeti oluşturması.
* Gezinme Durumu: Kullanıcının bir önceki sayfada nerede kaldığı, hangi öğelerin açık olduğu gibi oturuma özel arayüz durumlarını korumak.
* Oturuma Özel Mesajlar: Yalnızca o oturumda görüntülenecek bildirimler veya hata mesajları.
Temel Metotlar
sessionStorage nesnesi, localStorage ile tamamen aynı metod setine sahiptir:
* sessionStorage.setItem(key, value): Belirtilen anahtar ile değeri sessionStorage‘a kaydeder.
* sessionStorage.getItem(key): Belirtilen anahtara karşılık gelen değeri döndürür.
* sessionStorage.removeItem(key): Belirtilen anahtara sahip öğeyi sessionStorage‘dan siler.
* sessionStorage.clear(): sessionStorage‘daki tüm öğeleri siler.
* sessionStorage.key(index): Belirtilen dizindeki anahtarın adını döndürür.
* sessionStorage.length: sessionStorage‘daki depolanmış öğelerin sayısını döndürür.
Örnek Kullanım
Aşağıdaki JavaScript kod örnekleri, sessionStorage‘ın temel metotlarını göstermektedir:
// 1. Veri Kaydetme (setItem)
sessionStorage.setItem('formAdim1Verileri', '{"ad":"Deniz", "soyad":"Yılmaz"}');
sessionStorage.setItem('geciciMesaj', 'Hoş geldiniz! Bu mesaj sadece bu oturum için geçerlidir.');
console.log('Session verileri kaydedildi.');
// 2. Veri Okuma (getItem)
const formVerileriJSON = sessionStorage.getItem('formAdim1Verileri');
if (formVerileriJSON) {
const formVerileriObjesi = JSON.parse(formVerileriJSON);
console.log('Kaydedilen form verileri:', formVerileriObjesi);
console.log('Ad:', formVerileriObjesi.ad); // Çıktı: Deniz
}
const geciciMesaj = sessionStorage.getItem('geciciMesaj');
console.log('Geçici mesaj:', geciciMesaj);
// 3. Veri Silme (removeItem)
sessionStorage.removeItem('geciciMesaj');
console.log('Geçici mesaj silindi.');
const mesajTekrarKontrol = sessionStorage.getItem('geciciMesaj');
console.log('Geçici mesaj (silindikten sonra):', mesajTekrarKontrol); // Çıktı: null
// 4. Tüm Verileri Silme (clear)
// Dikkat: Bu işlem o sekmedeki tüm sessionStorage verilerini siler!
// sessionStorage.clear();
// console.log('Tüm sessionStorage verileri silindi.');
// 5. Anahtar Adına ve Uzunluğuna Erişim
console.log('Depolanan öğe sayısı:', sessionStorage.length);
for (let i = 0; i < sessionStorage.length; i++) {
const key = sessionStorage.key(i);
const value = sessionStorage.getItem(key);
console.log(Anahtar: ${key}, Değer: ${value});
}
Sınırlamalar ve Dikkat Edilmesi Gerekenler
sessionStorage, localStorage ile benzer sınırlamalara sahiptir:
* Sadece String Depolama: Tıpkı localStorage gibi, sessionStorage da sadece dize (string) verileri depolayabilir. Diğer veri türleri için JSON.stringify() ve JSON.parse() kullanılmalıdır.
* Senkron Çalışma: İşlemler senkrondur ve ana iş parçacığını bloke edebilir.
* Güvenlik Endişeleri (XSS): sessionStorage‘daki verilere de JavaScript aracılığıyla erişilebilir. XSS saldırıları, sessionStorage‘daki verileri çalabilir. Bu nedenle, hassas veriler burada da saklanmamalıdır.
* Veri Bütünlüğü: Kullanıcı tarafından değiştirilebilir, bu yüzden kritik uygulama mantığına temel oluşturmamalıdır.
* Depolama Limitleri: Genellikle 5-10 MB arasında bir depolama limiti vardır.
sessionStorage‘ın temel gücü, verilerin sadece belirli bir oturum için geçerli olmasıdır, bu da geçici ve oturuma özel veri yönetimi için idealdir.
localStorage ve sessionStorage Arasındaki Temel Farklar
localStorage ve sessionStorage aynı Web Storage API’sinin parçaları olup, aynı metod setini kullanmalarına rağmen, aralarındaki temel farklar kullanım senaryolarını büyük ölçüde etkiler. İşte bu iki mekanizma arasındaki ana farklılıklar:
| Özellik | localStorage | sessionStorage |
| :————- | :———————————————- | :——————————————— |
| Kalıcılık | Veriler kalıcıdır. Tarayıcı kapatılsa veya bilgisayar yeniden başlatılsa bile silinmez. Kullanıcı veya JavaScript tarafından açıkça silinene kadar kalır. | Veriler oturum bazlıdır. Tarayıcı sekmesi/penceresi kapatıldığında veya tarayıcı tamamen kapatıldığında silinir. |
| Kapsam | Aynı kökenden (domain) tüm sekmeler ve pencereler arasında paylaşılır. Bir sekmede kaydedilen veri, diğer sekmede erişilebilir. | Sadece veriyi oluşturan sekme veya pencere için geçerlidir. Farklı bir sekmede veya pencerede aynı site açılsa bile, o sekme için yeni ve boş bir sessionStorage alanı oluşturulur. |
| Ömür | Süresiz (persists indefinitely) | Oturum süresince (until tab/window is closed) |
| Kullanım Alanı | Kullanıcı tercihleri, çevrimdışı önbellekler, kalıcı alışveriş sepeti, uzun süreli oturum bilgileri. | Çok adımlı form verileri, oturuma özel filtreler/sıralamalar, geçici kullanıcı girdileri, tek oturumluk alışveriş sepeti. |
| Erişim | window.localStorage objesi üzerinden | window.sessionStorage objesi üzerinden |
Bu farklılıklar, bir web uygulamasında hangi depolama mekanizmasının kullanılacağına karar verirken anahtar rol oynar. Kalıcı ve domain genelinde paylaşılan verilere ihtiyacınız varsa localStorage, yalnızca mevcut oturum ve sekme için geçerli geçici verilere ihtiyacınız varsa sessionStorage tercih edilmelidir.
Web Storage API Güvenliği
Web Storage API’si (hem localStorage hem de sessionStorage), istemci tarafında veri depolama için güçlü ve kullanışlı bir mekanizma sunsa da, güvenlik hususları göz ardı edilmemelidir. Özellikle hassas verilerin depolanması konusunda dikkatli olunmalıdır.
XSS Saldırıları ve Önlemler
Web Storage’da depolanan verilere JavaScript aracılığıyla kolayca erişilebilir. Bu durum, siteler arası komut çalıştırma (XSS) saldırıları için bir risk oluşturur. Bir XSS saldırısında, kötü niyetli bir üçüncü taraf, web sitenize zararlı JavaScript kodu enjekte edebilir. Bu kod, localStorage veya sessionStorage‘daki tüm verilere erişebilir ve bunları saldırganın kontrolündeki bir sunucuya gönderebilir.
Önlemler:
* Asla Hassas Bilgiler Depolamayın: Şifreler, kredi kartı numaraları, kişisel kimlik numaraları, oturum çerezleri (cookie-based session IDs) gibi son derece hassas verileri localStorage veya sessionStorage‘da depolamaktan kaçının. Bu tür veriler için her zaman sunucu tarafında güvenli oturum yönetimi veya şifreleme yöntemleri kullanılmalıdır.
* Girişleri Temizleyin (Sanitize): Kullanıcı tarafından girilen herhangi bir veriyi tarayıcıda depolamadan önce veya HTML’ye yansıtmadan önce her zaman temizleyin ve doğrulayın. Bu, XSS saldırılarını önlemenin temelidir.
* İçerik Güvenlik Politikası (CSP): Bir İçerik Güvenlik Politikası (Content Security Policy) uygulamak, XSS saldırılarının etkisini azaltmaya yardımcı olabilir. CSP, tarayıcıya hangi kaynaklardan komut dosyalarının, stil sayfalarının ve diğer kaynakların yüklenebileceğini bildirir.
Hassas Veri Depolama
Daha önce de belirtildiği gibi, localStorage ve sessionStorage hassas verileri depolamak için uygun yerler değildir. Veriler tarayıcıda düz metin olarak saklanır ve kötü niyetli bir kod veya hatta tarayıcıya fiziksel erişimi olan bir kullanıcı tarafından kolayca okunabilir.
* Kimlik Doğrulama Tokenları: JWT (JSON Web Token) gibi kimlik doğrulama tokenları localStorage‘da depolanabilir, ancak bu bir tartışma konusudur. Eğer depolanacaksa, tokenların kısa ömürlü olması, her istekte sunucu tarafında doğrulanması ve refreshToken gibi mekanizmalarla desteklenmesi önemlidir. Daha güvenli bir yaklaşım, HttpOnly ve Secure bayraklarına sahip çerezlerde tokenları saklamaktır, çünkü bu çerezlere JavaScript erişemez ve sadece HTTPS üzerinden gönderilirler.
* Veri Şifreleme: Eğer gerçekten hassas verileri istemci tarafında depolamanız gerekiyorsa (ki bu genellikle tavsiye edilmez), bu verileri depolamadan önce istemci tarafında şifrelemeyi düşünebilirsiniz. Ancak bu, anahtarların yönetimi ve şifrelemenin doğru bir şekilde uygulanması gibi yeni karmaşıklıklar getirir ve yine de XSS riskini tamamen ortadan kaldırmaz.
Veri Bütünlüğü
localStorage ve sessionStorage‘daki veriler, kullanıcının tarayıcısında depolandığı için kullanıcı tarafından kolayca değiştirilebilir. Geliştirici araçlarını kullanarak veya doğrudan JavaScript konsolu üzerinden bu verilere erişilebilir ve manipüle edilebilir. Bu nedenle, uygulamanızın iş mantığını veya güvenlik kararlarını tamamen bu verilere dayandırmamalısınız. Her zaman sunucu tarafında veri doğrulaması ve yetkilendirme kontrolü yapılmalıdır.
Özetle, Web Storage API’si kolaylık ve performans sunar, ancak güvenlik her zaman öncelikli olmalıdır. Sadece hassas olmayan ve kullanıcı tarafından manipüle edilmesinin büyük risk oluşturmayacağı verileri depolamak için kullanılmalıdır.
Depolama Limitleri ve Yönetimi
Web Storage API’si, çerezlere kıyasla önemli ölçüde daha büyük bir depolama kapasitesi sunar. Tarayıcıya ve cihaza bağlı olarak, localStorage ve sessionStorage için genellikle 5 MB ila 10 MB arasında bir limit bulunur. Bu limit, her köken (origin) için ayrı ayrı uygulanır, yani bir web sitesinin kendi domain’i için bu kadar alana sahip olduğu anlamına gelir.
Limit Aşımı:
Eğer bir web uygulaması, belirlenen depolama limitini aşmaya çalışırsa, tarayıcı bir QuotaExceededError hatası fırlatacaktır. Bu hatayı yakalamak ve kullanıcıya uygun bir geri bildirim sağlamak önemlidir.
try {
localStorage.setItem('cokBuyukVeri', 'a'.repeat(10 1024 1024)); // 10MB veri
} catch (e) {
if (e.name === 'QuotaExceededError') {
console.error('Depolama alanı doldu! Daha fazla veri kaydedilemiyor.');
// Kullanıcıya bilgi ver veya eski verileri temizlemeyi dene
} else {
console.error('Bir hata oluştu:', e);
}
}
Depolama Alanı Yönetimi:
Web Storage API’si, kullanılan veya kalan depolama alanını doğrudan sorgulamak için yerleşik bir metod sunmaz. Ancak, geliştiriciler depolama alanını yönetmek için bazı stratejiler izleyebilir:
* Verimli Veri Saklama: Yalnızca gerçekten gerekli olan verileri depolayın. Büyük JSON nesnelerini sıkıştırarak veya sadece kritik alanlarını saklayarak alanı optimize edebilirsiniz.
* Eski Verileri Temizleme: Uygulamanızın artık ihtiyaç duymadığı eski veya süresi dolmuş verileri periyodik olarak removeItem() ile temizleyin.
* Alternatif Depolama Çözümleri: Eğer 5-10 MB’tan daha fazla depolama alanına veya yapılandırılmış veri depolama yeteneğine ihtiyacınız varsa, IndexedDB gibi daha gelişmiş istemci tarafı veritabanlarını düşünmelisiniz. IndexedDB, çok daha büyük veri kümelerini (genellikle GB’larca) ve karmaşık sorguları destekler.
Depolama limitleri, çoğu küçük ve orta ölçekli uygulama için yeterli olsa da, büyük ölçekli çevrimdışı uygulamalar veya çok miktarda kullanıcı verisi depolayan uygulamalar için dikkatle yönetilmesi gereken bir faktördür.
Web Storage API’nin Alternatifleri
localStorage ve sessionStorage birçok kullanım senaryosu için ideal çözümler olsa da, tüm istemci tarafı depolama ihtiyaçlarını karşılamazlar. Web platformu, farklı gereksinimlere yönelik başka depolama mekanizmaları da sunar.
Cookies (Çerezler)
* Tekrar Ziyaret: Çerezler, sunucuya yapılan her HTTP isteğiyle birlikte otomatik olarak gönderildiği için, özellikle sunucu tarafında oturum yönetimi veya kullanıcı takibi için hala kullanılırlar.
* Boyut ve Güvenlik: 4 KB’lık küçük boyutları ve her istekte gönderilmeleri nedeniyle büyük miktarda veri depolamak veya performans odaklı senaryolar için uygun değildirler. HttpOnly ve Secure bayrakları ile XSS saldırılarına karşı daha güvenli hale getirilebilirler.
* Kullanım Alanı: Oturum ID’leri, kullanıcı kimlik doğrulama tokenları (güvenli bir şekilde), A/B testi grupları gibi sunucu-istemci etkileşimi gerektiren küçük veriler.
IndexedDB
* Yapılandırılmış ve Büyük Veri: IndexedDB, tarayıcıda büyük miktarda yapılandırılmış veri depolamak için tasarlanmış, düşük seviyeli bir API’dir. İlişkisel veritabanlarına benzer bir nesne tabanlı veritabanı sistemidir.
* Asenkron: Tüm işlemleri asenkrondur, bu da ana iş parçacığının bloke olmamasını sağlar ve kullanıcı arayüzünün duyarlılığını korur.
* Kullanım Alanı: Çevrimdışı uygulamalar, büyük miktarda kullanıcı verisi (örneğin, e-posta istemcisi, not uygulaması), karmaşık veri sorgulama gerektiren uygulamalar.
* Karmaşıklık: Web Storage’a göre çok daha karmaşık bir API’ye sahiptir ve öğrenme eğrisi daha diktir. Genellikle IndexedDB’yi kolaylaştıran kütüphaneler (örneğin Dexie.js) kullanılır.
Cache API (Service Workers ile)
* Ağ Kaynakları Önbellekleme: Cache API, Service Worker’lar aracılığıyla web uygulamasının ağ isteklerini (HTML, CSS, JavaScript dosyaları, görseller vb.) önbelleğe almasını sağlar. Bu, çevrimdışı çalışma ve uygulamanın yükleme hızını artırmak için kritik öneme sahiptir.
* Programlanabilir Önbellek: Geliştiricilere, ağ isteklerini nasıl ele alacakları (önbellekten mi sunulacak, ağdan mı çekilecek vb.) üzerinde tam kontrol sağlar.
* Kullanım Alanı: Progresif Web Uygulamaları (PWA), çevrimdışı önbellekleme, statik kaynakların hızlı sunumu.
Application Cache (Uygulama Önbelleği – Kullanımdan Kaldırıldı)
* Geçmiş: HTML5 ile tanıtılan ancak karmaşıklığı, güvenilirlik sorunları ve esneklik eksikliği nedeniyle büyük ölçüde kullanımdan kaldırılmış (deprecated) bir teknolojidir.
* Yerine Geçen: Cache API ve Service Worker’lar tarafından tamamen ikame edilmiştir.
Özetle, localStorage ve sessionStorage basit anahtar-değer depolama ihtiyaçları için harikadır. Daha karmaşık ve büyük ölçekli veri depolama için IndexedDB, ağ kaynaklarını çevrimdışı hale getirmek için ise Cache API ve Service Worker’lar en iyi seçeneklerdir. Doğru aracı seçmek, uygulamanızın performansını, güvenliğini ve sürdürülebilirliğini etkileyecektir.
En İyi Uygulamalar ve İpuçları
localStorage ve sessionStorage‘ı etkin ve güvenli bir şekilde kullanmak için bazı en iyi uygulamaları ve ipuçlarını takip etmek önemlidir:
* Hata Yönetimi (Try-Catch Blokları): Web Storage işlemleri her zaman başarılı olmayabilir. Kullanıcı, tarayıcısını “gizli modda” kullanıyor olabilir (bu durumda depolama kotası çok küçük veya hiç olmayabilir) veya depolama alanı dolmuş olabilir. Bu durumları ele almak için her zaman try-catch blokları kullanın:
try {
localStorage.setItem('myKey', 'myValue');
} catch (e) {
if (e.name === 'QuotaExceededError') {
console.error('Depolama alanı doldu veya gizli modda erişim kısıtlı.');
} else {
console.error('Web Storage hatası:', e);
}
}
* Anahtarları Ön Eklerle Belirleme (Prefixing Keys): Özellikle büyük uygulamalarda veya farklı modüllerin veri depoladığı durumlarda, anahtar adlandırma çakışmalarını önlemek için anahtarlarınıza bir ön ek (prefix) ekleyin.
localStorage.setItem('myapp_user_id', '123');
localStorage.setItem('myapp_settings_theme', 'dark');
* JSON ile Nesne Depolama: localStorage ve sessionStorage sadece string depolayabildiği için, karmaşık JavaScript nesnelerini veya dizilerini depolarken JSON.stringify() kullanarak dizeye dönüştürün ve alırken JSON.parse() kullanarak orijinal haline getirin.
const user = { name: 'Ayşe', age: 30 };
localStorage.setItem('userProfile', JSON.stringify(user));
const storedUser = JSON.parse(localStorage.getItem('userProfile'));
console.log(storedUser.name);
* Hassas Verileri Depolamaktan Kaçının: Şifreler, kredi kartı bilgileri, kişisel kimlik numaraları gibi hassas verileri asla Web Storage’da saklamayın. XSS saldırılarına karşı savunmasızdırlar.
* Veri Bütünlüğünü Göz Önünde Bulundurun: localStorage ve sessionStorage‘daki veriler istemci tarafından kolayca değiştirilebilir. Uygulamanızın kritik mantığını bu verilere tamamen dayandırmayın ve sunucu tarafında her zaman doğrulama yapın.
* storage Olayını Kullanma (localStorage için): localStorage‘da bir değişiklik olduğunda (aynı kökenden farklı bir sekmede bile), window.onstorage olayı tetiklenir. Bu olay, sekmeler arası iletişimi sağlamak veya verilerin güncellendiğini diğer sekmelere bildirmek için kullanılabilir. sessionStorage için bu olay tetiklenmez çünkü veriler sekme bazlıdır.
window.addEventListener('storage', (event) => {
if (event.key === 'myapp_settings_theme') {
console.log('Tema ayarı değişti:', event.newValue);
// Sayfayı yeni temaya göre güncelle
}
});
* Kullanıcıya Bilgi Verme: Uygulamanızın neden veri depoladığını ve bu verilerin ne için kullanıldığını (örneğin, kişiselleştirme veya çevrimdışı işlevsellik için) kullanıcılara şeffaf bir şekilde açıklayın. GDPR gibi gizlilik düzenlemelerine uyum sağlamak önemlidir.
* Düzenli Temizleme: Uygulamanızın artık ihtiyaç duymadığı eski veya geçersiz verileri düzenli olarak temizleyerek depolama alanını verimli kullanın.
Bu ipuçlarını uygulayarak, Web Storage API’sinin avantajlarından tam olarak yararlanırken olası riskleri en aza indirebilirsiniz.
Sonuç
localStorage ve sessionStorage, modern web uygulamalarının istemci tarafında veri depolama ihtiyaçlarını karşılamak için tasarlanmış güçlü ve esnek araçlardır. Çerezlerin sınırlamalarını aşarak, daha büyük depolama kapasitesi, daha basit bir API ve sunucuya gereksiz veri gönderimi yapmama gibi önemli avantajlar sunarlar.
localStorage, verilerin kalıcı olarak saklanmasını sağlayarak kullanıcı tercihleri, çevrimdışı önbellekler ve uzun süreli oturum bilgileri gibi senaryolar için idealdir. Tarayıcı kapatılsa bile veriler kaybolmaz ve aynı kökenden tüm sekmeler arasında paylaşılabilir.
sessionStorage ise, verilerin yalnızca mevcut tarayıcı oturumu (sekme/pencere) boyunca geçerli olmasını sağlayarak çok adımlı formlar, geçici kullanıcı girdileri ve oturuma özel arayüz durumları gibi geçici veri depolama ihtiyaçları için mükemmeldir. Sekme kapatıldığında veriler silinir ve farklı sekmeler arasında paylaşılmaz.
Her iki mekanizma da setItem, getItem, removeItem ve clear gibi aynı basit metod setini kullanır ve sadece string verileri depolayabilirler. Bu nedenle, nesnelerin JSON.stringify() ve JSON.parse() ile dönüştürülmesi gereklidir.
Ancak, Web Storage API’si kullanılırken güvenlik hususları asla göz ardı edilmemelidir. Özellikle XSS saldırılarına karşı savunmasız oldukları için, şifreler veya kredi kartı bilgileri gibi hassas veriler asla localStorage veya sessionStorage‘da saklanmamalıdır. Verilerin kullanıcı tarafından manipüle edilebileceği gerçeği de dikkate alınmalı ve sunucu tarafında her zaman doğrulama yapılmalıdır.
Sonuç olarak, localStorage ve sessionStorage, doğru kullanıldığında web uygulamalarının performansını, kullanıcı deneyimini ve işlevselliğini önemli ölçüde artıran değerli araçlardır. Geliştiricilerin, uygulamanın ihtiyaçlarına en uygun depolama mekanizmasını seçerken kalıcılık, kapsam, güvenlik ve depolama limitleri gibi faktörleri dikkatlice değerlendirmesi, başarılı ve güvenli bir web uygulaması geliştirmek için kritik öneme sahiptir. Daha karmaşık depolama ihtiyaçları için IndexedDB veya çevrimdışı önbellekleme için Cache API gibi alternatifler de göz önünde bulundurulmalıdır.
