WisarWisar
Dasturlash kitobi/2-QISM — JavaScript10 daqiqa

2.17-bob: Browser APIs — localStorage, sessionStorage, fetch, Intersection Observer

2-QISM — JavaScript (0 dan chuqurgacha) · 17-mavzu


1. Kirish va motivatsiya

DOM 2.16-bob — brauzer beradigan API'lardan bittasi edi. Brauzer JS'ga yana ko'plab kuchli imkoniyatlar beradi: ma'lumotni saqlash (localStorage), tarmoq (fetch — 2.11), element ko'rinishini kuzatish (Intersection Observer), geolokatsiya, notification va boshqalar.

Browser API — brauzer JS'ga taqdim etadigan tayyor funksiyalar to'plami (0.5: brauzer modullari). Ular JS tilining o'zi emas (Node'da yo'q), balki brauzer muhiti beradigan qo'shimchalar.

O'xshatish: JS tili — asbob (bolg'a, arra). Browser API'lar — ustaxonadagi maxsus mashinalar (saqlash shkafi, telefon, kamera). Siz ularni ishlatasiz, lekin ularni o'zingiz yasamaysiz — brauzer beradi.

Bu bobda eng ko'p ishlatiladigan API'larni o'rganamiz: localStorage (ma'lumotni saqlash), fetch (tarmoq — 2.11 amaliyoti), Intersection Observer (lazy loading, infinite scroll). Bular real ilovalarning ajralmas qismi.


2. Nazariya — chuqur tushuntirish

2.1. Web Storage: localStorage va sessionStorage

Brauzerda ma'lumotni saqlash (sahifa yangilansa ham qoladi) — Web Storage API:

js
// localStorage — DOIMIY (o'chirmaguncha qoladi)
localStorage.setItem("til", "uz");        // saqlash (faqat MATN!)
localStorage.getItem("til");              // "uz" (o'qish)
localStorage.removeItem("til");           // o'chirish
localStorage.clear();                     // hammasini o'chirish

// sessionStorage — bir SESSIYA (tab yopilsa o'chadi)
sessionStorage.setItem("vaqtinchalik", "x");

localStorage vs sessionStorage:

localStorage sessionStorage
Muddat doimiy (o'chirmaguncha) tab yopilguncha
Ko'lam barcha tab (bir origin) faqat o'sha tab
Hajm ~5–10 MB ~5 MB

Faqat MATN saqlaydi. Obyekt/massiv saqlash uchun JSON.stringify 2.8-bob; o'qishda JSON.parse:

js
localStorage.setItem("user", JSON.stringify({ ism: "Ali" }));
const user = JSON.parse(localStorage.getItem("user"));   // obyekt

2.2. Storage qachon ishlatiladi (va ishlatilmaydi)

  • Yaxshi: til/mavzu sozlamasi, savat (mehmon), forma qoralamasi, oxirgi ko'rilganlar, "qayta ko'rsatma" bayroqlari.
  • Yomon: maxfiy ma'lumot (token, parol — XSS bilan o'g'irlanadi, 14); katta ma'lumot (limit ~5MB); muhim ma'lumot (foydalanuvchi o'chiradi).

Token saqlash: localStorage'da JWT saqlash — keng tarqalgan, lekin XSS xavfi bor (14). Xavfsizroq — httpOnly cookie 5.15-bob. Buni 5 va 14-boblarda ko'ramiz.

Cookie — kichik ma'lumot, har so'rovda serverga avtomatik yuboriladi (0.4: HTTP header). Auth 5.15-bob uchun muhim:

js
document.cookie = "til=uz; max-age=3600; path=/";   // o'qish/yozish (noqulay)

Cookie vs localStorage: cookie serverga yuboriladi (auth), localStorage — faqat brauzerda. httpOnly cookie JS'dan ko'rinmaydi (XSS himoyasi — 14). Auth uchun cookie afzal 5.15-bob.

2.4. fetch — tarmoq (2.11 takror + chuqurroq)

fetch 2.11-bob — HTTP so'rov 0.4-bob; Promise qaytaradi:

js
async function malumotOl(url) {
  const res = await fetch(url);                  // GET (default)
  if (!res.ok) throw new Error(`HTTP ${res.status}`);   // 0.4 — tekshir!
  return res.json();
}

// POST — sozlamalar bilan (0.4, 2.11)
async function yubor(url, data) {
  const res = await fetch(url, {
    method: "POST",
    headers: { "Content-Type": "application/json" },   // 0.4
    body: JSON.stringify(data),                         // obyekt  JSON (2.8)
  });
  return res.json();
}

2.5. fetch — qo'shimcha imkoniyatlar

js
// Header (auth token — 5.15)
fetch(url, { headers: { Authorization: `Bearer ${token}` } });

// AbortController — so'rovni bekor qilish (timeout/component unmount)
const controller = new AbortController();
fetch(url, { signal: controller.signal });
controller.abort();                              // so'rovni to'xtatadi

// Turli javob turlari
res.json();      // JSON (2.8)
res.text();      // matn
res.blob();      // fayl/rasm (binary — 0.1)

2.6. Intersection Observer — ko'rinishni kuzatish

Intersection Observer — element ekranda ko'rinib qolganini kuzatadi (scroll'ni qo'lda tekshirmasdan — samarali). Lazy loading, infinite scroll, animatsiya uchun:

js
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {        // element ko'rindi!
      console.log("Ko'rindi:", entry.target);
      // masalan: rasmni yukla, animatsiya boshla
      observer.unobserve(entry.target);  // bir marta — kuzatishni to'xtat
    }
  });
});

// Kuzatiladigan elementlarni qo'sh
document.querySelectorAll(".lazy").forEach(el => observer.observe(el));

Nega yaxshi: eski usul — scroll event'da har piksel uchun pozitsiya hisoblash (sekin, 0.5). Intersection Observer — brauzer samarali kuzatadi, faqat ko'ringanda xabar beradi. Lazy image, infinite scroll, "fade-in on scroll" uchun ideal.

2.7. Boshqa foydali API'lar (qisqacha)

js
// Geolocation — joylashuv
navigator.geolocation.getCurrentPosition(pos => {
  console.log(pos.coords.latitude, pos.coords.longitude);
});

// Clipboard — nusxalash
await navigator.clipboard.writeText("nusxalangan matn");

// Notification — bildirishnoma (ruxsat so'raydi)
Notification.requestPermission();

// History — URL boshqaruvi (SPA routing — 11.9)
history.pushState({}, "", "/yangi-sahifa");

// matchMedia — JS'da media query (1.5)
window.matchMedia("(max-width: 768px)").matches;   // mobil-mi?

Yana uchta — kundalik ishda tez-tez kerak bo'ladigan API'lar:

js
// 1) FormData — formani osongina yig'ish/yuborish (fayl ham — 5.11)
const form = document.querySelector("form");
const fd = new FormData(form);          // barcha input'larni name->value qilib oladi
fd.append("qoshimcha", "qiymat");
await fetch("/yuborish", { method: "POST", body: fd });  // multipart avtomatik

// 2) URL va URLSearchParams — URL va query (?a=1&b=2) bilan ishlash
const url = new URL("https://api.uz/qidir?q=kitob&sahifa=2");
url.searchParams.get("q");              // "kitob"
url.searchParams.set("sahifa", "3");    // o'zgartirish
console.log(url.toString());            // ".../qidir?q=kitob&sahifa=3"

// 3) requestAnimationFrame — silliq animatsiya (setInterval'dan afzal)
function animatsiya() {
  // har kadrda (60fps) chaqiriladi — brauzer tayyor bo'lganda
  requestAnimationFrame(animatsiya);
}
requestAnimationFrame(animatsiya);

requestAnimationFrame nega setInterval'dan yaxshi? U brauzerning chizish (repaint — 0.5) ritmiga moslashadi: tab ko'rinmasa to'xtaydi (batareya tejaydi), kadr tushib qolmaydi. Animatsiya uchun doim shuni ishlating. FormData esa fayl yuklashda (<input type="file"> — 5.11) ajralmas.


3. Sintaksis — tez ma'lumotnoma

js
// Web Storage (2.1)
localStorage.setItem(k, JSON.stringify(v))   // obyekt uchun stringify!
JSON.parse(localStorage.getItem(k))
localStorage.removeItem(k)  .clear()
sessionStorage.*   // tab yopilguncha

// fetch (2.4, 2.11)
const res = await fetch(url, { method, headers, body });
if (!res.ok) throw ...;  await res.json();

// Intersection Observer (2.6)
const obs = new IntersectionObserver(cb, options);
obs.observe(el);  obs.unobserve(el);  obs.disconnect();

4. Batafsil kod namunalari

Misol 1 — localStorage bilan sozlama saqlash (2.1)

js
// Mavzu (theme) sozlamasini saqlash — sahifa yangilansa ham qoladi
function mavzuOrnat(mavzu) {
  document.body.className = mavzu;            // DOM (2.16)
  localStorage.setItem("mavzu", mavzu);      // saqlash (2.1)
}

// Sahifa ochilganda — saqlanganni tikla
const saqlangan = localStorage.getItem("mavzu") ?? "yorug'";  // standart (2.1)
mavzuOrnat(saqlangan);

document.querySelector("#tema").addEventListener("click", () => {
  const yangi = document.body.className === "qorong'u" ? "yorug'" : "qorong'u";
  mavzuOrnat(yangi);
});

Misol 2 — Obyekt saqlash (JSON bilan — 2.1, 2.8)

js
const SAVAT_KEY = "savat";

function savatniOl() {
  return JSON.parse(localStorage.getItem(SAVAT_KEY)) ?? [];   // yo'q bo'lsa [] (2.1)
}
function savatniSaqla(savat) {
  localStorage.setItem(SAVAT_KEY, JSON.stringify(savat));     // obyekt  matn (2.8)
}
function qosh(mahsulot) {
  const savat = savatniOl();
  savatniSaqla([...savat, mahsulot]);        // immutable (2.7, 2.8)
}

Misol 3 — fetch bilan ma'lumot va localStorage cache (2.4, 0.1)

js
async function userOl(id) {
  const kalit = `user_${id}`;
  // 1) Cache'da bormi? (0.1: caching)
  const cache = localStorage.getItem(kalit);
  if (cache) return JSON.parse(cache);

  // 2) Yo'q — tarmoqdan ol (2.4, 2.11)
  const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);   // 0.4
  const user = await res.json();

  localStorage.setItem(kalit, JSON.stringify(user));    // cache'la (2.1)
  return user;
}

Misol 4 — Lazy loading (Intersection Observer — 2.6)

js
// Rasmlarni faqat ko'ringanda yuklash (boshlang'ich yuklanish tez — 0.5)
const observer = new IntersectionObserver((entries, obs) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;        // data-src  src (haqiqiy yuklash)
      obs.unobserve(img);               // bir marta (2.6)
    }
  });
}, { rootMargin: "100px" });            // 100px oldin yukla (silliq)

document.querySelectorAll("img[data-src]").forEach(img => observer.observe(img));

5. To'g'ri va noto'g'ri holatlar

1) localStorage'ga obyektni to'g'ridan-to'g'ri

js
//  obyekt  "[object Object]" (faqat matn — 2.1)
localStorage.setItem("user", { ism: "Ali" });

//  JSON.stringify
localStorage.setItem("user", JSON.stringify({ ism: "Ali" }));

2) Maxfiy ma'lumotni localStorage'da

js
//  token localStorage'da — XSS bilan o'g'irlanadi (2.2, 14)
localStorage.setItem("token", jwt);

//  httpOnly cookie 5.15-bob — JS ko'rmaydi, xavfsizroq

3) getItem null'ni tekshirmaslik

js
//  yo'q bo'lsa null  JSON.parse(null) muammosi (2.1)
const arr = JSON.parse(localStorage.getItem("yoq"));   // null

//  standart
const arr = JSON.parse(localStorage.getItem("yoq")) ?? [];

4) Scroll event'da pozitsiya (Observer o'rniga)

js
//  scroll'da har piksel hisoblash — sekin (0.5)
window.addEventListener("scroll", () => { /* getBoundingClientRect har safar */ });

//  Intersection Observer — samarali (2.6)

6. Keng tarqalgan xatolar va yechimlari

Xato 1 — localStorage'dan "[object Object]"

Sababi: obyekt stringifysiz saqlangan 2.1-bob. Yechimi: JSON.stringify saqlashda, JSON.parse o'qishda.

Xato 2 — JSON.parse xatosi (storage'dan)

Sababi: buzuq yoki null qiymat (2.8, 2.12). Yechimi: try/catch 2.12-bob yoki ?? standart 2.1-bob.

Xato 3 — QuotaExceededError

Sababi: localStorage limiti (~5MB) to'ldi. Yechimi: kam ma'lumot saqlang; katta uchun IndexedDB yoki server.

Xato 4 — fetch CORS xatosi

Sababi: boshqa domen ruxsat bermadi (0.4, 5.20). Yechimi: server CORS sozlasin (frontend hal qilolmaydi — 0.4).

Xato 5 — Intersection Observer ishlamaydi

Sababi: element DOM'da yo'q (kuzatishdan oldin), yoki observe chaqirilmadi. Yechimi: DOM tayyor bo'lgach observe 0.5-bob; selektorni tekshiring.


7. Integratsiya — bu mavzu stack'ning qayerida uchraydi

  • fetch/async 2.11-bob: tarmoq so'rovlari — Browser API.
  • DOM 2.16-bob: storage + DOM — to'liq ilova (To-Do — 2.16 loyihasi).
  • Axios 2.18-bob: fetch'ga muqobil — keyingi bob.
  • Auth (5.15, 14): token saqlash — localStorage vs httpOnly cookie.
  • React (11): useEffectda localStorage/fetch; custom hook (useLocalStorage).
  • Performance (0.5, 11): Intersection Observer — lazy load, infinite scroll.
  • Caching (0.1, 5.21): localStorage cache (Misol 3) — Redis g'oyasining brauzer versiyasi.

8. Eng yaxshi amaliyotlar (best practices)

  • localStorage faqat matn — obyekt uchun JSON.stringify/parse 2.1-bob.
  • getItem null'ni ushlang?? standart yoki try/catch (2.1, 2.12).
  • Maxfiy ma'lumotni localStorage'da saqlama (token — httpOnly cookie, 5.15, 14).
  • fetch'da res.ok tekshiring (0.4, 2.4).
  • Scroll-asosli ish uchun Intersection Observer (scroll event emas — 2.6, 0.5).
  • AbortController bilan keraksiz so'rovni bekor qiling (component unmount — 2.5, 11).
  • Storage kalitlarini doimiy (const) tuting — imlo xatosidan qoching.
  • localStorage limitini (~5MB) eslang — katta ma'lumotni serverda/IndexedDB.

9. Amaliy loyiha: "Sozlamali, Cache'li Ma'lumot Ko'rsatuvchi"

Browser API'larni birlashtiruvchi loyiha.

Maqsad

localStorage, fetch va Intersection Observer'ni birlashtirib, sozlamalarni saqlovchi, ma'lumotni cache'lovchi va lazy-load qiluvchi ilova qurish.

Talablar (requirements)

  1. Mavzu (theme) almashtirish: yorug'/qorong'u, localStorage'da saqlang, sahifa ochilganda tiklang (Misol 1).
  2. Ma'lumot olish + cache: ochiq API'dan (masalan postlar/userlar) ma'lumot oling; localStorage'da cache'lang — ikkinchi marta tarmoqsiz (Misol 3, 0.1).
  3. Cache muddati: cache'ga vaqt belgisi (timestamp — 2.9) qo'shing; 5 daqiqadan eski bo'lsa — qayta oling (bonus).
  4. Lazy loading: rasmlarni Intersection Observer bilan faqat ko'ringanda yuklang (Misol 4, 2.6).
  5. Infinite scroll (bonus): sahifa oxiriga yetganda (Observer) keyingi ma'lumotni yuklang.
  6. Forma qoralamasi: input'ga yozilganni localStorage'da saqlang (input event — 2.16); sahifa yangilansa tiklang.
  7. Xato boshqaruvi: tarmoq xatosi, JSON xatosi, storage to'lishi — try/catch 2.12-bob.
  8. localStorage'da obyekt JSON bilan; null tekshirilsin 2.1-bob.

Maslahatlar (hint)

  • Mavzu: localStorage.setItem("mavzu", ...) + document.body.className 2.16-bob.
  • Cache: {data, timestamp} saqlang; Date.now() - timestamp > 5*60*1000 bo'lsa eski 2.9-bob.
  • Lazy: <img data-src="..."> + Observer'da img.src = img.dataset.src (Misol 4).
  • Infinite scroll: oxirgi elementni kuzating; ko'ringanda yangi ma'lumot.
  • Qoralama: input event'da localStorage.setItem; ochilganda valueni tiklang.
  • Storage obyekt uchun JSON.stringify/parse 2.8-bob.

"Tayyor" mezonlari (acceptance criteria)

  • Mavzu saqlanadi va sahifa ochilganda tiklanadi.
  • Ma'lumot cache'lanadi (ikkinchi marta tarmoqsiz).
  • Lazy loading Observer bilan ishlaydi.
  • Forma qoralamasi saqlanadi/tiklanadi.
  • localStorage obyekt JSON bilan; null tekshirilgan.
  • Xatolar try/catch bilan ushlangan.
  • (Bonus) Cache muddati yoki infinite scroll.

Yechim kodi ataylab berilmagan — bu loyihani o'zingiz yozib ko'ring.


10. Xulosa va keyingi bobga ko'prik

Bu bobda brauzerning kuchli API'larini o'rgandik:

  • Web Storage: localStorage (doimiy) vs sessionStorage (tab); faqat matn — obyekt uchun JSON.stringify/parse. Maxfiy ma'lumotni saqlama (XSS — 14).
  • Cookie — serverga yuboriladi (auth — 5.15); httpOnly xavfsiz.
  • fetch 2.11-bob — tarmoq; header, AbortController, javob turlari.
  • Intersection Observer — ko'rinishni samarali kuzatish (lazy load, infinite scroll) — scroll event'dan afzal 0.5-bob.
  • Boshqa: Geolocation, Clipboard, History (SPA — 11.9), matchMedia 1.5-bob.

Keyingi bob — 2.18-bob: Axios — so'rovlar, interceptors. fetch (2.11, 2.17) — native, lekin real loyihada ko'pincha Axios kutubxonasi ishlatiladi: avtomatik JSON, xatoni qulay boshqarish, va eng muhimi — interceptorlar (har so'rovga token qo'shish, global xato — 5.15). Bu — 2-QISMning so'nggi bobi!


Foydalanilgan rasmiy/ishonchli manbalar

  • MDN Web Docs — Web Storage API (localStorage/sessionStorage), Window.localStorage
  • MDN Web Docs — Fetch API, AbortController, Intersection Observer API
  • MDN Web Docs — cookie, Geolocation, Clipboard, History API

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
2.17-bob: Browser APIs — localStorage, sessionStorage, fetch, Intersection Observer — Wisar