fetch()
, XMLHttpRequest'e (XHR) benzer ağ istekleri yapmanıza olanak tanır. Temel fark, Fetch API'nin, XMLHttpRequest API'deki karmaşık geri çağırmalardan kaçınmanıza yardımcı olacak daha basit bir API'ye sahip olan Promises'i kullanmasıdır.
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 istemek, yanıt almak ve bunu JSON olarak ayrıştırmak istiyoruz.
XMLHttpRequest
Bir XMLHttpRequest
için, başarı ve hata durumlarını ele almak üzere iki dinleyiciye ve open()
ile send()
'ye çağrı gerekir.
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ğinin, XHR örneğiyle aynı işi yapması için yalnızca bir çağrı olması gerekir. 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, Response 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 üstbilgileri 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.
Getirme istekleri için bir mod tanımlayabilirsiniz. Böylece yalnızca belirli istek türleri çözümlenir. Ayarlayabileceğiniz modlar şunlardır:
same-origin
, yalnızca aynı kaynaktaki öğe istekleri için başarılı olur ve diğer tüm istekleri reddeder.cors
, aynı kaynaktaki ve uygun COR başlıklarını döndüren diğer kaynaklardaki öğe isteklerine izin verir.cors-with-forced-preflight
, herhangi bir istek yapmadan önce ön uç kontrol gerçekleştirir.no-cors
öğesinin, CORS başlıkları olmayan veopaque
yanıtıyla sonuçlanan diğer kaynaklara istek göndermesi amaçlanmıştır. Ancak belirtildiği gibi , bu işlem şu anda pencere global kapsamında mümkün değildir.
Modu tanımlamak için fetch
isteğine ikinci parametre olarak bir options 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
Vaatlerin en güzel özelliklerinden biri, bunları bir araya getirme yeteneğidir. fetch()
için bu, getirme istekleri arasında mantığı paylaşmanıza olanak tanır.
Bir JSON API ile çalışıyorsanız durumu kontrol etmeniz ve her yanıt için JSON'yi 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ı, tüm getirme isteklerinizde mantığı paylaşmanıza olanak tanıyarak kodun bakımını, okunmasını ve test edilmesini kolaylaştırır.
POST İsteği
Bazen bir web uygulamasının POST yöntemi olan 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'
})