Getir() işlevine giriş

Matt Gaunt

fetch(), XMLHttpRequest (XHR)'ye benzer ağ istekleri göndermenize olanak tanır. Temel fark, Fetch API'nin Promise'leri kullanmasıdır. Promise'ler, XMLHttpRequest API'sindeki karmaşık geri çağırmalardan kaçınmanıza yardımcı olmak için daha basit bir API'ye sahiptir.

Tarayıcı desteği

  • Chrome: 42.
  • Edge: 14.
  • Firefox: 39.
  • Safari: 10.1.

Kaynak

Daha önce Promises kullanmadıysanız JavaScript Promises'e Giriş başlıklı makaleyi inceleyin.

Temel Getirme İsteği

Aşağıda, XMLHttpRequest ile ve ardından fetch ile uygulanan bir örnek verilmiştir. Bir URL isteğinde bulunmak, yanıt almak ve yanıtı JSON olarak ayrıştırmak istiyoruz.

XMLHttpRequest

XMLHttpRequest, başarı ve hata durumlarını işlemek için iki dinleyiciye ve open() ile send() çağrısına ihtiyaç duyar. MDN dokümanlarından örnek.

function reqListener () {
  const data = JSON.parse(this.responseText);
  console.log(data);
}

function reqError (err) {
  console.log('Fetch Error :-S', err);
}

const oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();

Getir

Getirme isteğimiz şu şekilde görünür:

fetch('./api/some.json')
  .then(response => {
    if (response.status !== 200) {
      console.log(`Looks like there was a problem. Status Code: ${response.status}`);

      return;
    }

    // Examine the text in the response
    response.json().then(function(data) {
      console.log(data);
    });
  })
  .catch(err => {
    console.log('Fetch Error :-S', err);
  });

fetch() isteği, XHR örneğiyle aynı işi yapmak için yalnızca bir çağrıya ihtiyaç duyar. Yanıtı işlemek için önce yanıt durumunun 200 olup olmadığını kontrol eder, ardından yanıtı JSON olarak ayrıştırırız. fetch() isteğinin yanıtı bir Stream nesnesi olduğundan json() yöntemini çağırdıktan sonra bir Promise döndürülür. Akış, eşzamansız olarak gerçekleşir.

Yanıt Meta Verileri

Önceki örnekte, Yanıt nesnesinin durumu ve yanıtın JSON olarak nasıl ayrıştırılacağı gösterilmiştir. Erişmek isteyebileceğiniz diğer meta verileri (ör. üstbilgi) nasıl işleyeceğiniz aşağıda açıklanmıştır:

fetch('users.json').then(response => {
  console.log(response.headers.get('Content-Type'));
  console.log(response.headers.get('Date'));

  console.log(response.status);
  console.log(response.statusText);
  console.log(response.type);
  console.log(response.url);
});

Yanıt Türleri

Getirme isteği yaptığımızda yanıta "basic", "cors" veya "opaque" değerinde bir response.type verilir. Bu types, kaynağın nereden geldiğini gösterir ve yanıt nesnesini nasıl işleyeceğinizi belirlemek için bunları kullanabilirsiniz.

Tarayıcı aynı kaynakta bir kaynak istediğinde, yanıtta, yanıttan görüntüleyebileceğiniz öğelerle ilgili kısıtlamalar içeren bir basic türü bulunur.

Başka bir kaynaktaki bir kaynak için istek yapılırsa ve bu kaynak CORs üst bilgilerini döndürür ise tür cors olur. cors yanıtları, basic yanıtlarına benzer ancak görüntüleyebileceğiniz üstbilgileri Cache-Control, Content-Language, Content-Type, Expires, Last-Modified ve Pragma ile sınırlandırır.

opaque yanıtları, CORS üstbilgilerini döndürmeyen farklı bir kaynaktan geliyor. Şeffaf olmayan bir yanıt aldığımızda döndürülen verileri okuyamaz veya isteğin durumunu görüntüleyemeyiz. Bu durumda, isteğin başarılı olup olmadığını kontrol edemezsiniz.

Yalnızca belirli istek türlerinin çözülmesi için getirme isteği için bir mod tanımlayabilirsiniz. Ayarlayabileceğiniz modlar şunlardır:

  • same-origin yalnızca aynı kaynaktaki öğelerle ilgili istekler için başarılı olur ve diğer tüm istekleri reddeder.
  • cors, aynı kaynaktaki ve uygun CORS üst bilgilerini döndüren diğer kaynaklardaki öğelerin isteklerine izin verir.
  • cors-with-forced-preflight, herhangi bir istek yapmadan önce ön uç kontrol gerçekleştirir.
  • no-cors, CORS üstbilgileri olmayan diğer kaynaklara istek göndermek ve opaque yanıtıyla sonuçlanmak için tasarlanmıştır ancak belirtildiği gibi , bu şu anda window global kapsamında mümkün değildir.

Modu tanımlamak için fetch isteğinde ikinci parametre olarak bir seçenekler nesnesi ekleyin ve modu bu nesnede tanımlayın:

fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'})
  .then(response => response.text())
  .then(text => {
    console.log('Request successful', text);
  })
  .catch(error => {
    log('Request failed', error)
  });

Söz zincirleme

Promise'lerin en iyi özelliklerinden biri, bunları birbirine zincirleme imkanı sunmasıdır. fetch() için bu, mantığı getirme isteklerinde paylaşmanıza olanak tanır.

JSON API ile çalışıyorsanız her yanıt için durumu kontrol etmeniz ve JSON'u ayrıştırmanız gerekir. Durumu ve JSON ayrıştırmayı, söz döndüren ayrı işlevlerde tanımlayarak kodunuzu basitleştirebilir ve yalnızca nihai verileri ve hata durumunu işlemek için fetch isteğini kullanabilirsiniz.

function status (response) {
  if (response.status >= 200 && response.status < 300) {
    return Promise.resolve(response)
  } else {
    return Promise.reject(new Error(response.statusText))
  }
}

function json (response) {
  return response.json()
}

fetch('users.json')
  .then(status)
  .then(json)
  .then(data => {
    console.log('Request succeeded with JSON response', data);
  }).catch(error => {
    console.log('Request failed', error);
  });

Bu örnekte, response.status değerini kontrol eden ve Promise.resolve() olarak çözülmüş bir Promise veya Promise.reject() olarak reddedilmiş bir Promise döndüren bir status işlevi tanımlanmaktadır. Bu, fetch() zincirinde çağrılan ilk yöntemdir.

Sözleşme çözülürse komut dosyası json() yöntemini çağırır. Bu yöntem, response.json() çağrısından ikinci bir Promise döndürür ve ayrıştırılmış JSON'u içeren bir nesne oluşturur. Ayrıştırma başarısız olursa Promise reddedilir ve catch ifadesi yürütülür.

Bu yapı, mantığı tüm getirme isteklerinizde paylaşmanıza olanak tanır. Böylece kodun bakımı, okunması ve test edilmesi kolaylaşır.

POST İsteği

Bazen bir web uygulamasının, POST yöntemiyle bir API'yi çağırması ve isteğin gövdesine bazı parametreler eklemesi gerekir. Bunu yapmak için fetch() seçeneklerinde method ve body parametrelerini ayarlayın:

fetch(url, {
    method: 'post',
    headers: {
      "Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
    },
    body: 'foo=bar&lorem=ipsum'
  })
  .then(json)
  .then(data => {
    console.log('Request succeeded with JSON response', data);
  })
  .catch(error => {
    console.log('Request failed', error);
  });

Getirme isteğiyle kimlik bilgileri gönderme

Çerezler gibi kimlik bilgileri içeren bir getirme isteği göndermek için isteğin credentials değerini "include" olarak ayarlayın:

fetch(url, {
  credentials: 'include'
})