Tarmoq so'rovlari

Fetch

JavaScript brauzerdan serverga so'rovlar yuborib, ma'lumot olib kelishi mumkin. Buning zamonaviy usuli โ€” fetch() metodi. U sahifani qayta yuklamasdan serverdan ma'lumot olishga imkon beradi (bu yondashuv AJAX deb ataladi). Ushbu darsda fetch qanday ishlashini, javobni qanday o'qishni va xatoliklarni qanday boshqarishni chuqur o'rganamiz.

Muhim: fetch, XMLHttpRequest va WebSocket โ€” bular brauzer muhitiga xos (yoki Node.js'da alohida sozlanadigan) asinxron mexanizmlardir. Shu sababli ushbu bobdagi kod misollari asosan statik โ€” ularni playground darhol ishga tushirib natija bermaydi, chunki ular haqiqiy tarmoq va brauzer API'lariga bog'liq. Har bir misolni tushunib o'qing.

fetch(url) sintaksisi

Eng sodda ko'rinishda fetchga faqat URL beriladi:

let promise = fetch(url, [options]);

fetch chaqirilishi bilanoq brauzer tarmoq so'rovini boshlaydi va promise qaytaradi. Bu promise ikki bosqichda hal bo'ladi.

Ikki bosqichli javob

fetchning eng muhim xususiyati โ€” javob ikki bosqichda keladi.

Birinchi bosqich: server sarlavhalar (headers) bilan javob berishi bilanoq, fetch qaytargan promise Response obyekti bilan bajariladi. Bu bosqichda javobning HTTP holatini (status) tekshirishimiz mumkin, ammo tana (body) hali kelib bo'lmagan bo'lishi mumkin.

let response = await fetch(url);

if (response.ok) {
  // HTTP holati 200-299 oralig'ida bo'lsa
  let json = await response.json();
} else {
  alert('HTTP xatolik: ' + response.status);
}

Ikkinchi bosqich: javob tanasini (body) olish uchun qo'shimcha metod chaqiramiz. Bu metod ham asinxron va promise qaytaradi, chunki katta hajmdagi ma'lumot tarmoq orqali asta-sekin kelishi mumkin.

Nima uchun ikki bosqich? Chunki sarlavhalar tez keladi, tana esa katta bo'lishi mumkin (masalan, katta rasm yoki fayl). Sarlavhalarni oldindan olib, javob turi va holatini bilgan holda, tanani o'qishni boshlashimiz mumkin.

Response holati: status va ok

Response obyektining holatini bildiruvchi ikkita muhim xossasi bor:

let response = await fetch('https://example.com/data');

console.log(response.status); // masalan, 200
console.log(response.ok);     // true (agar 200-299 bo'lsa)
Diqqat: fetch HTTP xatolik holatlarida (masalan, 404 yoki 500) promise'ni rad etmaydi (reject qilmaydi)! Server javob bergani โ€” muvaffaqiyat deb hisoblanadi. Promise faqat tarmoq umuman ishlamasa (server topilmasa, internet uzilsa) rad etiladi. Shuning uchun HTTP holatini o'zimiz response.ok orqali tekshirishimiz shart.

Javob tanasini o'qish metodlari

Response obyekti tanani turli formatlarda o'qish uchun bir nechta metod taqdim etadi. Har biri promise qaytaradi:

Muhim cheklov: tanani faqat bitta metod bilan o'qish mumkin. Agar response.text() chaqirsak, keyin response.json() ishlamaydi, chunki tana allaqachon o'qib bo'lingan. Ikkalasi kerak bo'lsa, birini tanlab, kerak bo'lsa qayta ishlang.

JSON javobni o'qish

Amalda eng ko'p ishlatiladigan format โ€” JSON. response.json() tanani o'qib, uni JavaScript obyektiga aylantiradi:

let response = await fetch('https://api.example.com/users/1');
let user = await response.json();

console.log(user.name);  // obyektning maydonlariga kira olamiz
console.log(user.email);

Bu yerda ikkita await bor: birinchisi javob sarlavhalarini kutadi, ikkinchisi tanani to'liq o'qib, JSON'ni tahlil qiladi.

Matnli javobni o'qish

Agar server oddiy matn qaytarsa (masalan, HTML yoki oddiy qator), response.text()dan foydalanamiz:

let response = await fetch('https://example.com/hello.txt');
let text = await response.text();

console.log(text); // faylning matn mazmuni

.then() bilan yozish

fetch promise qaytargani uchun uni .then() zanjiri bilan ham ishlatish mumkin. Quyidagi ikkala usul teng:

// .then() zanjiri bilan
fetch('https://api.example.com/data')
  .then(function (response) {
    if (!response.ok) {
      throw new Error('HTTP xatolik: ' + response.status);
    }
    return response.json();
  })
  .then(function (data) {
    console.log(data);
  })
  .catch(function (error) {
    console.log('So'rov muvaffaqiyatsiz: ' + error.message);
  });
Zamonaviy koda odatda async/await afzal ko'riladi โ€” u tekis va o'qishga oson. .then() esa eski kodda yoki ba'zi maxsus holatlarda uchraydi.

async/await bilan xatoliklarni boshqarish

Amaliy koda so'rovni try...catch ichiga o'rab, ikki turdagi xatolikni ham qamrab olamiz: tarmoq xatoligi (fetch reject bo'ladi) va HTTP xatoligi (o'zimiz tekshiramiz).

async function malumotOl(url) {
  try {
    let response = await fetch(url);

    // HTTP holatini tekshiramiz
    if (!response.ok) {
      throw new Error('HTTP xatolik! Holat: ' + response.status);
    }

    let data = await response.json();
    return data;

  } catch (error) {
    // Bu yerga ikki holatda tushamiz:
    // 1) tarmoq ishlamadi (fetch reject bo'ldi)
    // 2) yuqorida o'zimiz throw qildik (HTTP xatolik)
    console.log('Xatolik: ' + error.message);
    throw error; // xatolikni yuqoriga uzatamiz (ixtiyoriy)
  }
}

// Foydalanish:
malumotOl('https://api.example.com/users')
  .then(function (users) {
    console.log('Foydalanuvchilar soni: ' + users.length);
  })
  .catch(function () {
    console.log('Ma'lumot olib bo'lmadi');
  });
Bu shabloni yaxshi eslab qoling: await fetch โ†’ response.ok tekshirish โ†’ await response.json(), hammasini try...catch ichida. Bu real loyihalarda deyarli har doim shunday yoziladi.

Response sarlavhalari (headers)

Javob bilan kelgan sarlavhalarni response.headers orqali o'qish mumkin. Bu Map'ga o'xshash maxsus obyekt:

let response = await fetch(url);

// Bitta sarlavhani olish
console.log(response.headers.get('Content-Type'));
// masalan: application/json; charset=utf-8

// Barcha sarlavhalarni aylanib chiqish
for (let [key, value] of response.headers) {
  console.log(key + ': ' + value);
}

Xulosa