Getir() işlevine giriş

Matt Gaunt

fetch(), XMLHttpRequest'e (XHR) benzer ağ istekleri yapmanıza olanak tanır. Temel fark, Fetch API'nin Promise'leri kullanmasıdır. Bu API, XMLHttpRequest API'deki karmaşık geri çağırmalardan kaçınmanıza yardımcı olacak daha basit bir API'ye sahiptir.

Browser Support

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

Source

Daha önce hiç Promise kullanmadıysanız JavaScript Promise'lerine Giriş başlıklı makaleyi inceleyin.

Temel getirme isteği

Aşağıda, önce XMLHttpRequest, ardından fetch ile uygulanan bir örnek verilmiştir. Bir URL isteyip yanıt almak ve bu 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 belgelerinden ö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 şekildedir:

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ğine verilen yanıt bir Stream nesnesidir. Bu, json() yöntemini çağırdıktan sonra bir Promise döndürüldüğü anlamına gelir. Akış, eşzamansız olarak gerçekleşir.

Yanıt meta verileri

Önceki örnekte, Response nesnesinin durumu ve yanıtın JSON olarak nasıl ayrıştırılacağı gösterilmiştir. Üstbilgiler gibi erişmek isteyebileceğiniz diğer meta verileri 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

Bir getirme isteği gönderdiğimizde yanıtın response.type değeri "basic", "cors" veya "opaque" olur. Bu types, kaynağın nereden geldiğini gösterir ve yanıt nesnesine nasıl davranılacağını belirlemek için kullanılabilir.

Tarayıcı aynı kaynakta bir kaynak istediğinde yanıt, yanıttan neleri görüntüleyebileceğinizle ilgili kısıtlamalar içeren bir basic türüne sahip olur.

Başka bir kaynaktaki bir kaynak için istekte bulunulursa ve bu kaynak CORS üstbilgileri döndürürse tür cors olur. cors yanıtları, basic yanıtlarına benzer ancak görüntüleyebileceğiniz başlıkları Cache-Control, Content-Language, Content-Type, Expires, Last-Modified ve Pragma ile sınırlandırır.

opaque yanıtları, CORS başlıkları döndürmeyen farklı bir kaynaktan geliyor. Opak bir yanıtla, döndürülen verileri okuyamaz veya isteğin durumunu görüntüleyemeyiz. Bu da isteğin başarılı olup olmadığını kontrol edemeyeceğiniz anlamına gelir.

Yalnızca belirli istek türlerinin çözümlenmesi için getirme isteğiyle ilgili bir mod tanımlayabilirsiniz. Aşağıdaki modları ayarlayabilirsiniz:

  • same-origin yalnızca aynı kaynaktaki öğelerle ilgili isteklerde başarılı olur ve diğer tüm istekleri reddeder.
  • cors, aynı kaynaktaki ve uygun CORS başlıklarını döndüren diğer kaynaklardaki öğeler için isteklere izin verir.
  • cors-with-forced-preflight, herhangi bir istekte bulunmadan önce ön kontrol gerçekleştirir.
  • no-cors, CORS başlıkları olmayan diğer kaynaklara istek göndermek ve opaque yanıtı almak için tasarlanmıştır ancak belirtildiği gibi , bu şu anda pencere global kapsamında mümkün değildir.

Modu tanımlamak için fetch isteğine 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)
  });

Promise zincirleme

Promise'lerin en iyi özelliklerinden biri, birbirine zincirlenebilmeleridir. fetch() için bu, getirme istekleri arasında mantık paylaşmanıza olanak tanır.

JSON API ile çalışıyorsanız her yanıtın durumunu kontrol etmeniz ve JSON'u ayrıştırmanız gerekir. Durumu ve JSON ayrıştırmayı, promise 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 çözümlenmiş bir Promise'i Promise.resolve() olarak veya reddedilmiş bir Promise'i Promise.reject() olarak döndüren bir status işlevi tanımlanmaktadır. Bu, fetch() zincirinde çağrılan ilk yöntemdir.

Promise çözümlenirse 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 isteği

Bazen bir web uygulamasının POST yöntemiyle bir API'yi çağırması ve isteğin gövdesine bazı parametreler eklemesi gerekir. Bunun 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);
  });

Kimlik bilgilerini getirme isteğiyle gönderme

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

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