1 AÄŸustos 2023

Fetch API

Şimdiye kadar fetch hakkında biraz bilgi edindik.

Şimdi tamamını kapsayacak şekilde API’nin tüm yeteneklerini görelim.

Varsayılan değerleriyle olası tüm fetch işlemlerinin tam listesi işte burada (diğer alternatifler yorumlarda)

let promise = fetch(url, {
  method: "GET", // POST, PUT, DELETE vb.
  headers: {
    "Content-Type": "text/plain;charset=UTF-8" // for a string body, depends on body
  },
  body: undefined // string, FormData, Blob, BufferSource ya da URLSearchParams
  referrer: "about:client", // no-referrer için "" ya da mevcut başlangıç noktasından bir URL
  referrerPolicy: "no-referrer-when-downgrade", // no-referrer, origin, same-origin...
  mode: "cors", // same-origin, no-cors
  credentials: "same-origin", // omit, include
  cache: "default", // no-store, reload, no-cache, force-cache ya da only-if-cached
  redirect: "follow", // manual, error
  integrity: "", // bir hash, "sha256-abcdef1234567890" gibi
  keepalive: false, // true
  signal: undefined, // İsteği iptal etmek için AbortController
  window: window // null
});

Etkileyici bir liste, deÄŸil mi?

Fetch: Temel Bilgiler bölümünde method, headers ve body tamamıyla ele alındı .

signal ise Fetch: Abort bölümünde ele alındı.

Şimdi diğer özelliklerini inceleyelim.

referrer, referrerPolicy

Bu özellikler fetch işleminin HTTP Referer bilgisini nasıl ayarladığını düzenler.

Bu başlık, istek yapan sayfanın URL’sini içerir. Çoğu durumda çok küçük bir bilgilendirme rolü oynar ama bazen güvenlik amacıyla kaldırmak veya değiştirmek daha mantıklıdır.

referrer özelliği başlangıçtaki mevcut herhangi bir Referer’ın ayarlanmasına veya devre dışı bırakılmasına izin verir.

Referer göndermemek için boş bir string yazın:

fetch('/page', {
  referrer: "" // Referer içeriği boş
});

Mevcut başlangıç noktasında başka bir URL ayarlamak için:

fetch('/page', {
  // https://javascript.info’da olduğumuzu varsayarsak
  // herhangi bir Referer bilgisini ayarlayabiliriz ancak sadece mevcut başlangıç noktası dahilinde
  referrer: "https://javascript.info/anotherpage"
});

referrerPolicy, Referer için genel kurallar belirler.

Olası değerler Referrer Policy spesifikasyonunda açıklanmıştır:

  • "no-referrer-when-downgrade" – Varsayılan deÄŸer: HTTPS’ten HTTP’ye bir istek göndermediÄŸimiz sürece Referer her zaman gönderilir (güvenlik protokolü daha az).
  • "no-referrer" – Hiçbir zaman Referer göndermez.
  • "origin" – Belli bir URL’yi deÄŸil, sadece Referer kaynağını gönderir. ÖrneÄŸin http://site.com/path yerine http://site.com gibi.
  • "origin-when-cross-origin" – Referer’ın tamamını aynı kaynaÄŸa gönderir ancak kaynaklar arasındaki istekler için yalnızca kaynak kısmını gönderir.
  • "same-origin" – Aynı kök URL’ye tam Referer gönderir, ancak farklı kök URL’ler arasındaki istekler için Referer göndermez.
  • "strict-origin" – Sadece kök URL’yi gönderir, HTTPS→HTTP istekleri için Referer göndermez.
  • "strict-origin-when-cross-origin" – Aynı kök URL’ye tam Referer gönderir, farklı kök URL’ler arasındaki istekler için sadece kök URL gönderir ancak HTTPS→HTTP isteÄŸi durumunda hiçbir ÅŸey göndermez.
  • "unsafe-url" – Her zaman Referer’da tam URL’yi gönderir.

Diyelim ki dışarıdan görünmemesi gereken URL yapılarına sahip bir yönetici bölgesi (admin zone) var.

Eğer farklı bir kaynaktan (cross-origin) bir istek gönderirsek varsayılan olarak isteğimiz Referer başlığını sayfanın tam URL’siyle birlikte gönderir (ancak HTTPS’ten HTTP’ye istek gönderdiğimizde Referer gönderilmez).

Örneğin Referer: https://javascript.info/admin/secret/paths.

Referrer’ı tamamen gizleme istiyorsak:

fetch('https://another.com/page', {
  referrerPolicy: "no-referrer" // no Referer, referrer: ""'la aynı işlevi görür
});

Aksi takdirde, uzak tarafın isteğin nereden geldiğini görmesini istiyorsak, sadece URL’nin “origin” (kök) kısmını gönderebiliriz:

fetch('https://another.com/page', {
  referrerPolicy: "strict-origin" // Referer: https://javascript.info
});

mode

mode seçeneği, kaynaklararası istekleri önlemek için bir güvenlik önlemi olarak hizmet eder.

  • "cors" – Varsayılan olarak Fetch: Cross-Origin Requests’de açıklandığı gibi kaynaklararası isteklere izin verilir,
  • "same-origin" – Kaynaklararası isteklere izin verilmez,
  • "no-cors" – Sadece basit olan kaynaklararası isteklere izin verilir.

Bu, fetch işleminin URL’sinin üçüncü taraf bir kaynaktan geldiği durumlarda ve kaynaklararası yeteneklerini sınırlamak için bir “güç kapama anahtarı” istediğimiz durumlarda faydalı olabilir.

credentials

credentials, fetch işleminin isteğiyle birlikte çerezleri ve HTTP-Authorization başlıklarını gönderip göndermeyeceğini belirtir.

  • "same-origin" – Varsayılan deÄŸerdir, kaynaklararası istekler için göndermez,
  • "include" – Her zaman gönderir ancak kaynaklararası sunucudan Accept-Control-Allow-Credentials gerektirir,
  • "omit" – Hiçbir zaman göndermez hatta aynı kök URL’ye sahip istekler için bile göndermez.

cache

Varsayılan olarak fetch istekleri standart HTTP önbellekleme kurallarını kullanır. Yani Expires, Cache-Control başlıklarını dikkate alıp If-Modified-Since gibi başlıklar gönderir. Adeta normal HTTP istekleri gibi davranır.

cache, HTTP önbelleğini yok saymak veya kullanımını ayarlamak için kullanılır:

  • "default" – fetch, standart HTTP önbellekleme kurallarını ve baÅŸlıklarını kullanır;
  • "no-store" – HTTP önbelleÄŸini tamamen yok sayar. EÄŸer If-Modified-Since, If-None-Match, If-Unmodified-Since, If-Match veya If-Range baÅŸlıklarından herhangi birini set edersek bu mod varsayılan olur;
  • "reload" – Sonucu HTTP önbellekten almadan (eÄŸer varsa) cevap ile önbelleÄŸi doldurur (eÄŸer cevap baÅŸlıkları buna izin veriyorsa);
  • "no-cache" – Önbellekte bir yanıt varsa koÅŸullu bir istek oluÅŸturur aksi takdirde normal bir istek yapar. HTTP önbelleÄŸi ile cevabı doldurur;
  • "force-cache" – Yanıtı HTTP önbelleÄŸinden alır hatta eskimiÅŸ olsa bile. EÄŸer HTTP önbelleÄŸinde yanıt yoksa normal bir HTTP isteÄŸi yapar ve normal davranır;
  • "only-if-cached" – Yanıtı HTTP önbelleÄŸinden alır hatta eskimiÅŸ olsa bile. EÄŸer HTTP önbelleÄŸinde yanıt yoksa hata döner. Sadece mode deÄŸeri "same-origin" olduÄŸunda çalışır.

redirect

Normalde fetch işlemi 301, 302 gibi HTTP yönlendirmelerini şeffaf bir şekilde takip eder.

redirect seçeneği bu davranışı değiştirmemizi sağlar:

  • "follow" – Varsayılan deÄŸerdir, HTTP yönlendirmelerini takip eder,
  • "error" – HTTP yönlendirmesi durumunda hata verir,
  • "manual" – HTTP yönlendirmelerini takip etmez ancak response.url yeni URL olacak ve response.redirected deÄŸeri true olacak böylece ihtiyaç halinde yönlendirmeyi manuel olarak yeni URL’ye gerçekleÅŸtirebiliriz.

integrity

integrity, yanıtın önceden bilinen bir karma (checksum) ile eşleşip eşleşmediğini kontrol etmemize olanak sağlar.

specification’da açıklandığı gibi, desteklenen fonksiyonlar SHA-256, SHA-384 ve SHA-512’dir ve tarayıcıya göre başka fonksiyonları da olabilir.

Örneğin bir dosyayı indiriyoruz ve dosyanın SHA-256 karma değerinin “abc” olduğunu biliyoruz (gerçek bir karma değeri tabii ki daha uzundur).

Bunu aşağıdaki gibi integrity seçeneğine ekleyebiliriz:

fetch('http://site.com/file', {
  integrity: 'sha256-abd'
});

Daha sonra fetch işlemi kendi başına SHA-256 hesaplar ve hesapladığı değeri bizim verdiğimiz değerle karşılaştırır. Eşleşme olmaması durumunda bir hata tetiklenir.

keepalive

keepalive, isteğin sayfadan ayrıldıktan sonra dahi gerçekleştirilebileceğini belirtir.

Örneğin mevcut ziyaretçinin sayfamızı nasıl kullandığıyla ilgili istatistikleri topluyoruz (fare tıklamaları, görüntülediği sayfa parçaları) ve kullanıcı deneyimini iyileştirmek amacıyla bunları sunucumuza kaydetmek istiyoruz.

Ziyaretçi sayfadan ayrıldığında bu bilgileri sunucumuza kaydetmek istiyoruz.

Bunu yapmak için window.onunload özelliğini kullanabiliriz:

window.onunload = function() {
  fetch('/analytics', {
    method: 'POST',
    body: "statistics",
    keepalive: true
  });
};

Normalde bir belge yüklenirken ilişkili tüm ağ istekleri iptal edilir ancak keepalive tarayıcının isteği arka planda yapmasını ve sayfadan ayrıldıktan sonra bile gerçekleştirmesini sağlar. Bu nedenle isteğin başarıyla gerçekleşmesi için bu seçeneğin kullanılması önemlidir.

  • Megabaytlarca veri gönderemeyiz: keepalive istekleri için sınır 64 KB’dır
    • Daha fazla veri toplarsak düzenli olarak göndermemiz gerekir böylece “onunload” isteÄŸi için çok fazla veri olmaz.
    • Limit tüm devam eden istekler için geçerlidir. Bu nedenle 64 KB boyutunda 100 istek oluÅŸturarak bu sınırı aÅŸabiliriz.
  • onunload durumunda sunucu cevabını alamayız çünkü belge o zaman zaten yüklenmemiÅŸtir.
    • Genellikle sunucu böyle isteklere boÅŸ bir cevap gönderir bu nedenle bu durumda bir sorun olmaz.
Eğitim haritası

Yorumlar

yorum yapmadan önce lütfen okuyun...
  • EÄŸer geliÅŸtirme ile alakalı bir öneriniz var ise yorum yerine github konusu gönderiniz.
  • EÄŸer makalede bir yeri anlamadıysanız lütfen belirtiniz.
  • Koda birkaç satır eklemek için <code> kullanınız, birkaç satır eklemek için ise <pre> kullanın. EÄŸer 10 satırdan fazla kod ekleyecekseniz plnkr kullanabilirsiniz)