JavaScript server bilan tarmoq soârovlarini yuborishi va kerakli paytda yangi maâlumotlarni yuklashi mumkin.
Masalan, biz tarmoq soârovidan quyidagilar uchun foydalanishimiz mumkin:
- Buyurtma yuborish,
- Foydalanuvchi maâlumotlarini yuklash,
- Serverdan eng soânggi yangilanishlarni olish,
- â¦va hokazo.
â¦Va bularning barchasini sahifani qayta yuklamasdan!
JavaScriptâdan tarmoq soârovlari uchun âAJAXâ (Asinxron JavaScript va XML) atamasi mavjud. Garchi XML ishlatishimiz shart emas: bu atama eski davrlardan qolgan, shuning uchun bu soâz mavjud. Bu atamani eshitgan boâlishingiz mumkin.
Tarmoq soârovini yuborish va serverdan maâlumot olishning bir nechta yoâli bor.
fetch() usuli zamonaviy va koâp qirrali, shuning uchun undan boshlaymiz. Eski brauzerlar tomonidan qoâllab-quvvatlanmaydi (polyfill qilinishi mumkin), lekin zamonaviy brauzerlar orasida juda yaxshi qoâllab-quvvatlanadi.
Asosiy sintaksis:
let promise = fetch(url, [options])
urlâ kirishga moâljallangan URL.optionsâ ixtiyoriy parametrlar: method, headers va boshqalar.
options boâlmasa, bu oddiy GET soârovi boâlib, url ning mazmunini yuklab oladi.
Brauzer soârovni darhol boshlaydi va chaqiruvchi kod natijani olish uchun ishlatishi kerak boâlgan promiseâni qaytaradi.
Javob olish odatda ikki bosqichli jarayon.
Birinchidan, server headers bilan javob berganda, fetch tomonidan qaytarilgan promise built-in Response klassining obyekti bilan resolve qilinadi.
Bu bosqichda biz HTTP statusni tekshirishimiz mumkin, u muvaffaqiyatli yoki yoâqligini koârish, headersâlarni tekshirish mumkin, lekin hali bodyâmiz yoâq.
Agar fetch HTTP-soârovni bajarish imkoniyatiga ega boâlmasa, masalan, tarmoq muammolari yoki bunday sayt mavjud boâlmasa, promise rad etiladi. 404 yoki 500 kabi gâayritabiiy HTTP-statuslar xatolikka sabab boâlmaydi.
HTTP-statusni response xususiyatlarida koârishimiz mumkin:
statusâ HTTP status kodi, masalan 200.okâ boolean, agar HTTP status kodi 200-299 boâlsatrue.
Masalan:
let response = await fetch(url);
if (response.ok) { // agar HTTP-status 200-299 bo'lsa
// response body'ni oling (usul quyida tushuntirilgan)
let json = await response.json();
} else {
alert("HTTP-Xato: " + response.status);
}
Ikkinchidan, response bodyâni olish uchun qoâshimcha method chaqiruvidan foydalanishimiz kerak.
Response bodyâga turli formatlarda kirish uchun bir nechta promise-asoslangan methodlarni taqdim etadi:
response.text()â javobni oâqish va matn sifatida qaytarish,response.json()â javobni JSON sifatida parse qilish,response.formData()â javobniFormDataobyekti sifatida qaytarish (keyingi bobda tushuntirilgan),response.blob()â javobni Blob sifatida qaytarish (turi bilan ikkilik maâlumot),response.arrayBuffer()â javobni ArrayBuffer sifatida qaytarish (ikkilik maâlumotlarning past darajadagi koârinishi),- qoâshimcha ravishda,
response.bodyâ ReadableStream obyekti, u bodyâni chunk-by-chunk oâqish imkonini beradi, keyinroq misolni koâramiz.
Masalan, GitHubâdan eng soânggi commitlar bilan JSON-obyektni olaylik:
let url = 'https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits';
let response = await fetch(url);
let commits = await response.json(); // response body'ni o'qish va JSON sifatida parse qilish
alert(commits[0].author.login);
Yoki, await boâlmagan holda, toza promises sintaksisi yordamida:
fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits')
.then(response => response.json())
.then(commits => alert(commits[0].author.login));
Response matnini olish uchun .json() oârniga await response.text():
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
let text = await response.text(); // response body'ni matn sifatida o'qish
alert(text.slice(0, 80) + '...');
Ikkilik formatda oâqishning namunasi sifatida, âfetchâ spetsifikatsiyasining logotip rasmini yuklab olaylik va koârsataylik (Blob operatsiyalari haqida batafsil maâlumot uchun Blob bobiga qarang):
let response = await fetch('/article/fetch/logo-fetch.svg');
let blob = await response.blob(); // Blob obyekti sifatida yuklash
// buning uchun <img> yaratish
let img = document.createElement('img');
img.style = 'position:fixed;top:10px;left:10px;width:100px';
document.body.append(img);
// ko'rsatish
img.src = URL.createObjectURL(blob);
setTimeout(() => { // uch soniyadan keyin yashirish
img.remove();
URL.revokeObjectURL(img.src);
}, 3000);
Biz faqat bitta body-oâqish usulini tanlashimiz mumkin.
Agar biz allaqachon response.text() bilan javob olgan boâlsak, response.json() ishlamaydi, chunki body mazmuni allaqachon qayta ishlangan.
let text = await response.text(); // response body iste'mol qilindi
let parsed = await response.json(); // ishlamaydi (allaqachon iste'mol qilingan)
Response headers
Response headers response.headers da Map-ga oâxshash headers obyektida mavjud.
Bu aynan Map emas, lekin nom boâyicha alohida headerâlarni olish yoki ularni takrorlash uchun shunga oâxshash methodlarga ega:
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
// bitta header olish
alert(response.headers.get('Content-Type')); // application/json; charset=utf-8
// barcha header'lar bo'ylab takrorlash
for (let [key, value] of response.headers) {
alert(`${key} = ${value}`);
}
Request headers
fetch da request headerâini oârnatish uchun headers opsiyasidan foydalanishimiz mumkin. Unda chiquvchi headerâlar bilan obyekt bor, masalan:
let response = fetch(protectedUrl, {
headers: {
Authentication: 'secret'
}
});
â¦Lekin oârnata olmaydigan taqiqlangan HTTP headerâlar roâyxati mavjud:
Accept-Charset,Accept-EncodingAccess-Control-Request-HeadersAccess-Control-Request-MethodConnectionContent-LengthCookie,Cookie2DateDNTExpectHostKeep-AliveOriginRefererTETrailerTransfer-EncodingUpgradeViaProxy-*Sec-*
Bu headerâlar toâgâri va xavfsiz HTTPâni taâminlaydi, shuning uchun ular faqat brauzer tomonidan nazorat qilinadi.
POST soârovlar
POST soârovini yoki boshqa method bilan soârov yaratish uchun fetch opsiyalaridan foydalanishimiz kerak:
methodâ HTTP-method, masalanPOST,bodyâ soârov tanasi, quyidagilardan biri:- string (masalan JSON-kodlangan),
FormDataobyekti, maâlumotlarniform/multipartsifatida yuborish uchun,- ikkilik maâlumotlarni yuborish uchun
Blob/BufferSource, - maâlumotlarni
x-www-form-urlencodedkodlashda yuborish uchun URLSearchParams, kamdan-kam ishlatiladi.
JSON format koâpincha ishlatiladi.
Masalan, bu kod user obyektini JSON sifatida yuboradi:
let user = {
name: 'John',
surname: 'Smith'
};
let response = await fetch('/article/fetch/post/user', {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(user)
});
let result = await response.json();
alert(result.message);
Diqqat qiling, agar soârov body string boâlsa, Content-Type header sukut boâyicha text/plain;charset=UTF-8 ga oârnatiladi.
Lekin, biz JSON yuborayotganimiz uchun, JSON-kodlangan maâlumotlar uchun toâgâri Content-Type boâlgan application/json ni yuborish uchun headers opsiyasidan foydalanamiz.
Rasm yuborish
Shuningdek, Blob yoki BufferSource obyektlari yordamida fetch bilan ikkilik maâlumotlarni yuborishimiz mumkin.
Ushbu misolda, ustida sichqonchani harakatlantirib chizish mumkin boâlgan <canvas> mavjud. âSubmitâ tugmasini bosish rasmni serverga yuboradi:
<body style="margin:0">
<canvas id="canvasElem" width="100" height="80" style="border:1px solid"></canvas>
<input type="button" value="Yuborish" 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/post/image', {
method: 'POST',
body: blob
});
// server tasdiqlash va rasm o'lchami bilan javob beradi
let result = await response.json();
alert(result.message);
}
</script>
</body>
Diqqat qiling, bu yerda Content-Type headerâini qoâlda oârnatmaymiz, chunki Blob obyekti oârnatilgan turga ega (bu yerda image/png, toBlob tomonidan yaratilgan). Blob obyektlari uchun bu tur Content-Type ning qiymatiga aylanadi.
submit() funksiyasini async/await boâlmagan holda quyidagicha qayta yozish mumkin:
function submit() {
canvasElem.toBlob(function(blob) {
fetch('/article/fetch/post/image', {
method: 'POST',
body: blob
})
.then(response => response.json())
.then(result => alert(JSON.stringify(result, null, 2)))
}, 'image/png');
}
Xulosa
Odatiy fetch soârovi ikkita await chaqiruvidan iborat:
let response = await fetch(url, options); // response headers bilan resolve qilinadi
let result = await response.json(); // body'ni json sifatida o'qish
Yoki, await boâlmagan holda:
fetch(url, options)
.then(response => response.json())
.then(result => /* natijani qayta ishlash */)
Response xususiyatlari:
response.statusâ javobning HTTP kodi,response.okâ agar status 200-299 boâlsatrue.response.headersâ HTTP headers bilan Map-ga oâxshash obyekt.
Response bodyâni olish usullari:
response.text()â javobni matn sifatida qaytarish,response.json()â javobni JSON obyekti sifatida parse qilish,response.formData()â javobniFormDataobyekti sifatida qaytarish (form/multipart kodlash, keyingi bobga qarang),response.blob()â javobni Blob sifatida qaytarish (turi bilan ikkilik maâlumot),response.arrayBuffer()â javobni ArrayBuffer sifatida qaytarish (past darajadagi ikkilik maâlumot),
Hozircha Fetch opsiyalari:
methodâ HTTP-method,headersâ soârov headers bilan obyekt (har qanday header ruxsat etilmagan),bodyâstring,FormData,BufferSource,BlobyokiUrlSearchParamsobyekti sifatida yuborish uchun maâlumot (soârov tanasi).
Keyingi boblarda biz fetch ning koâproq opsiyalari va foydalanish holatlarini koâramiz.
Izohlar
<code>yorlig'ini ishlating, bir nechta satrlar uchun - ularni<pre>yorlig'i bilan o'rab qo'ying, 10 satrdan ortiq bo'lsa - sandbox (plnkr, jsbin, codepenâ¦)