fetch() yöntemi, HTTP üzerinden istek göndermenin modern bir yoludur.
Birkaç yılda geliÅtirildi ve geliÅtirilmeye devam ediliyor, Åu anda tarayıcılar arasında desteÄi oldukça saÄlam.
Temel sözdizimi Åöyledir:
let promise = fetch(url, [options])
urlâ eriÅilecek URL.optionsâ isteÄe baÄlı parametreler: method, headers vb.
Tarayıcı isteÄi baÅlatır ve bir promise döndürür.
Yanıt alma iÅlemi genellikle iki aÅamalıdır.
Sunucu baÅlıklarını yanıtladıÄında, promise otomatik olarak oluÅturulmuÅ Response sınıfının bir nesnesiyle çözümlenir.
Bu Åekilde HTTP durumunu kontrol edebiliriz (status), baÅlıkları kontrol edebiliriz (head), ancak henüz gövdeyi (body) alamayız.
fetch, HTTP isteÄi yapamadıÄında (örneÄin, aÄ sorunları varsa veya böyle bir site yoksa)
promise, reddeder. 404 veya 500 gibi HTTP hataları bile normal akıŠolarak kabul edilir.
Bunları response özelliklerinde görebiliriz:
okâ boolean, HTTP durum kodu 200-299 ise true döndürür.statusâ HTTP durum kodu.
ÃrneÄin:
let response = await fetch(url);
if (response.ok) { // if HTTP-status is 200-299
// get the response body (see below)
let json = await response.json();
} else {
alert("HTTP-Error: " + response.status);
}
Response gövdesini (body) almak için, ek bir yöntem çaÄrısı yapmamız gerekiyor.
Response gövdesine eriÅmek için birden fazla format ve özellik vardır:
response.json()â yanıtı JSON nesnesi olarak ayrıÅtırır,response.text()â yanıtı metin (text) olarak döndürür,response.formData()â yanıtı FormData nesnesi olarak döndürür (form/çok parçalı kodlama),response.blob()â yanıtı Blob türünde döndürür Blob (binary data tipi (ikili)),response.arrayBuffer()â yanıtı ArrayBuffer türünde döndürür (saf ikili veri),- ek olarak,
response.bodybir, ReadableStream nesnesidir, gövdeyi parça parça okumaya izin verir, daha sonra bir örnek göreceÄiz.
ÃrneÄin, burada GitHubâdan en son commitleri içeren bir JSON nesnesi alıyoruz:
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
let commits = await response.json(); // yanıt gövdesini okuyun ve JSON olarak ayrıÅtırın
alert(commits[0].author.login);
Ya da promises sözdizimi kullanarak aynısını yapabilirsiniz:
fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits')
.then(response => response.json())
.then(commits => alert(commits[0].author.login));
Metni almak için:
let text = await response.text();
Ve binary örneÄi için, bir görsel getirelim ve gösterelim (bloblar üzerindeki iÅlemler hakkında ayrıntılar için Blob bölümüne bakın):
let response = await fetch('/article/fetch/logo-fetch.svg');
let blob = await response.blob(); // Blob nesnesi olarak indirme
// create <img> for it
let img = document.createElement('img');
img.style = 'position:fixed;top:10px;left:10px;width:100px';
document.body.append(img);
// Gösterme
img.src = URL.createObjectURL(blob);
setTimeout(() => { // 2 saniye sonra gizle
img.remove();
URL.revokeObjectURL(img.src);
}, 2000);
Yalnızca bir gövde ayrıÅtırma yöntemi seçebiliriz.
Yanıtı response.text() ile aldıysak, gövde içeriÄi zaten iÅlenmiÅ olduÄundan response.json() çalıÅmayacaktır.
let text = await response.text(); // yanıt gövdesi çevirildi
let parsed = await response.json(); // hata (yukarıda zaten çevirilmiÅti)
BaÅlıklar (Headers)
response.headers içinde Map benzeri bir headers nesnesi vardır.
BaÅlıkları tek tek alabilir veya üzerinde yineleme yapabiliriz:
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
// sadece bir baÅlık alma
alert(response.headers.get('Content-Type')); // application/json; charset=utf-8
// tüm baÅlıkları çekme
for (let [key, value] of response.headers) {
alert(`${key} = ${value}`);
}
Bir baÅlık ayarlamak için aÅaÄıdaki headers seçeneÄini deneyebilirsiniz:
let response = fetch(protectedUrl, {
headers: {
Authentication: 'abcdef'
}
});
â¦Ancak ayarlayamayacaÄımız yasaklı HTTP baÅlıklarının bir listesi var:
Accept-Charset,Accept-EncodingAccess-Control-Request-HeadersAccess-Control-Request-MethodConnectionContent-LengthCookie,Cookie2DateDNTExpectHostKeep-AliveOriginRefererTETrailerTransfer-EncodingUpgradeViaProxy-*Sec-*
Bu baÅlıklar düzgün ve güvenli HTTP isteÄi saÄlar, bu nedenle yalnızca tarayıcı tarafından kontrol edilirler.
POST istekleri
POST isteÄi veya baÅka bir yöntemle istek yapmak için fetch seçeneklerini kullanmamız gerekir:
methodâ HTTP-methodu, örn.POST,bodyâ örnekler:- string deÄer (örn. JSON),
FormDatanesnesi olarak göndermek içinform/multipart,Blob/BufferSourceikili (binary) veri göndermek için,- URLSearchParams, verileri
x-www-form-urlencoded, göndermek için, nadiren kullanılır.
Hadi örneklere bakalım.
Json Veri Göndermek
Bu kod bir user objesini JSON olarak gönderir:
let user = {
name: 'John',
surname: 'Smith'
};
let response = await fetch('/article/fetch-basics/post/user', {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(user)
});
let result = await response.json();
alert(result.message);
Kısa bir not, göndereceÄim deÄer string ise, Content-Type deÄerini text/plain;charset=UTF-8 olarak belirlememiz gerekiyor. Json veri göndereceÄimiz için headers objesine application/json özelliÄini ekliyoruz.
Form verisini göndermek
Aynı Åeyi bir HTML <form>'u ile yapalım.
<form id="formElem">
<input type="text" name="name" value="John">
<input type="text" name="surname" value="Smith">
</form>
<script>
(async () => {
let response = await fetch('/article/fetch-basics/post/user', {
method: 'POST',
body: new FormData(formElem)
});
let result = await response.json();
alert(result.message);
})();
</script>
Burada FormData formu otomatik olarak encode eder, <input type="file"> alanları iÅlenir ve, Content-Type: form/multipart olarak gönderir.
Görselleri göndermek
Görsel verisini gönderirken ikili (binary) veri olarak göndermemiz gerekir.
Direkt olarak Blob veya BufferSource kullanarak gönderebiliriz.
ÃrneÄin, burada fareyi hareket ettirerek çizim yapabileceÄimiz bir <canvas> var. âGönderâ butonuna tıklandıÄında görsel sunucuya gönderilir:
<body style="margin:0">
<canvas id="canvasElem" width="100" height="80" style="border:1px solid"></canvas>
<input type="button" value="Submit" onclick="submit()">
<script>
canvasElem.onmousemove = function(e) {
let ctx = canvasElem.getContext('2d');
ctx.lineTo(e.clientX, e.clientY);
ctx.stroke();
};
async function submit() {
let blob = await new Promise(resolve => canvasElem.toBlob(resolve, 'image/png'));
let response = await fetch('/article/fetch-basics/post/image', {
method: 'POST',
body: blob
});
let result = await response.json();
alert(result.message);
}
</script>
</body>
Burada ayrıca Content-Type manuel olarak ayarlamamız gerekmedi, çünkü Blob nesnesinin yerleÅik bir türü vardır (burada toBlob tarafından oluÅturulan image/png).
Ayrıca submit() fonksiyonu async/await olmadan Åu Åekilde yazabiliriz:
function submit() {
canvasElem.toBlob(function(blob) {
fetch('/article/fetch-basics/post/image', {
method: 'POST',
body: blob
})
.then(response => response.json())
.then(result => alert(JSON.stringify(result, null, 2)))
}, 'image/png');
}
Görsel içeren Formdataâyı göndermek
Pratikte bir görseli ânameâ ve diÄer meta veriler gibi ek alanlarla birlikte formun bir parçası olarak göndermek genellikle daha uygundur.
Ayrıca, sunucular genellikle ham ikili veriler yerine çok parçalı kodlanmıŠformları(multipart-encoded forms) kabul etmeye daha uygundur.
<body style="margin:0">
<canvas id="canvasElem" width="100" height="80" style="border:1px solid"></canvas>
<input type="button" value="Submit" onclick="submit()">
<script>
canvasElem.onmousemove = function(e) {
let ctx = canvasElem.getContext('2d');
ctx.lineTo(e.clientX, e.clientY);
ctx.stroke();
};
async function submit() {
let blob = await new Promise(resolve => canvasElem.toBlob(resolve, 'image/png'));
let formData = new FormData();
formData.append("name", "myImage");
formData.append("image", blob);
let response = await fetch('/article/fetch-basics/post/image-form', {
method: 'POST',
body: formData
});
let result = await response.json();
alert(result.message);
}
</script>
</body>
Åimdi, sunucu açısından bakıldıÄında, görsel formdaki bir "dosya "dır.
Ãzet
Tipik bir fetch isteÄi iki bölümden oluÅur awaits:
let response = await fetch(url, options); // baÅlık kurallara göre okunur
let result = await response.json(); // gövdeyi json olarak geri döndürü
Veya, promise stilinde:
```js
fetch(url, options)
.then(response => response.json())
.then(result => /* process result */)
Yanıt(Response) Ãzellikleri
response.statusâ HTTP durum kodunu içerir,response.okâtrueise deÄer 200-299 arası olmalıdırresponse.headersâ BaÅlıklarını içeren bir map benzeri nesne döndürür
Yanıt Gövdesini (Response Body) alma yöntemleri:
response.json()â yanıtı bir JSON objesine çevirir,response.text()â yanıtı bir text olarak döndürür,response.formData()â yanıtı bir FormData objesi olarak döndürür (form/multipart encoding),response.blob()â yanıtı Blob (binary data tipi) olarak döndürür,response.arrayBuffer()â yanıtı ArrayBuffer (saf ikili veri (binary)) olarak döndürür,
Åimdiye kadarki âFetchâ seçenekleri:
methodâ HTTP methodları (POST,GET vs,),headersâ istek baÅlıklarını içeren bir nesne (herhangi bir baÅlıÄa izin verilmez),bodyâ string/FormData/BufferSource/Blob/UrlSearchParams türünde gönderilecek veriler
Sonraki bölümlerde daha fazla seçenek ve kullanım durumu göreceÄiz.
Yorumlar
<code>kullanınız, birkaç satır eklemek için ise<pre>kullanın. EÄer 10 satırdan fazla kod ekleyecekseniz plnkr kullanabilirsiniz)