MakeFirstStep· Frontend + зеҳни сунъӣ

Дарси 14 · Async ва API

fetch ва HTTP

Қурби сомонӣ дар барномаи бонк, обу ҳавои Душанбе, рӯйхати мол дар дӯкони интернетӣ, ленти хабарҳо: ҳамаи инҳо на дар браузери шумо, балки дар компютерҳои бегона — серверҳо ҷойгиранд. Барои гирифтани маълумот аз он ҷо саҳифа дархости HTTP мефиристад ва ҷавобро интизор мешавад. Имрӯз шумо меомӯзед, ки инро бо JavaScript-и пок тавассути fetch иҷро кунед — ва печонандаи худии api.js-ро созед, ки онро дар ҳар лоиҳаи оянда истифода мебаред.

  • Шарҳ додан, ки дархости HTTP ва ҷавоб аз чӣ иборатанд: усул, URL, сарлавҳаҳо, бадан, статус
  • Фарқ кардани усулҳои GET, POST, PUT, PATCH, DELETE ва гурӯҳҳои рамзҳои статус 2xx / 3xx / 4xx / 5xx
  • Дархост кардан тавассути fetch ва хондани ҷавоб: response.json(), status, ok, headers
  • Фиристодани маълумот бо усули POST: сарлавҳаи Content-Type ва JSON.stringify
  • Фарқ кардани хатои шабакавӣ аз ҷавоби «404» ва коркарди ҳардуи онҳо тавассути response.ok ва try / catch
  • Сохтани печонандаи api.js ва санҷидани коде, ки ЗС навиштааст, дар ҷавобҳои хатоӣ
Бо ин саҳифа чӣ тавр кор кардан лозим

Коди дар заминаи торик бо тугмаи ▶ Иҷро кардан зинда аст. Дар ин дарс бисёр мисолҳо ба интернет мераванд (ба серверҳои таълимии jsonplaceholder ва dummyjson): як-ду сония интизор шавед, то ҷавоб ояд ва консол сатрҳоро пурра кунад. Агар интернет набошад, дархостҳо меафтанд — ва ин ҳам таҷрибаи судманд аст: дар поён мо чунин вазъиятҳоро коркард карданро меомӯзем. Як қисми вазифаҳо бе шабака кор мекунанд (дар онҳо мо худамон ҷавобҳои серверро «қалбакӣ» месозем) — онҳо фавран санҷида мешаванд. Ишораҳо зери қулфак 🔒 пинҳонанд.

01 HTTP: браузер бо сервер чӣ тавр гап мезанад

Муштарӣ (клиент) — ин браузери шумост (ё коди шумо дар он). Сервер — компютере, ки маълумот дар он ҷойгир аст. Онҳо мувофиқи қоидаҳои протоколи HTTP муошират мекунанд: клиент дархост (request) мефиристад, сервер ҷавоб (response) бармегардонад. Ҳамеша ба навбат: сервер худаш аввал навиштанро оғоз намекунад.

Қиёс аз ҳаёт

Шумо дар қаҳвахона назди Рӯдакӣ тавассути пешхизмат фармоиш медиҳед. Дархост: «Палав биёред (усул) (суроғаи хӯрок дар меню), бе сабзӣ (сарлавҳа бо хоҳишҳо)». Ҷавоб: пешхизмат бармегардад ва аввал статус мегӯяд — «Овардам» (200) ё «Чунин хӯрок нест» (404) ё «Ошпаз бемор шуд» (500), баъд баданаи ҷавобро — худи палавро — ба рӯи миз мегузорад.

Суроға аз чӣ иборат аст

Суроғаи захира URL номида мешавад. Он якчанд қисм дорад ва браузер онҳоро бо ёрии синфи дарунсохти URL таҷзия карда метавонад.

https://jsonplaceholder.typicode.com/todos?userId=1&_limit=3
Протокол — «чӣ тавр гап мезанем», хост — «бо кӣ», роҳ — «чиро металабем», параметрҳо — «возеҳкуниҳо»
URL-ро ба қисмҳо таҷзия мекунем · Ctrl + Enter
const url = new URL("https://jsonplaceholder.typicode.com/todos?userId=1&_limit=3");

console.log(url.protocol);               // https:
console.log(url.hostname);               // jsonplaceholder.typicode.com
console.log(url.pathname);               // /todos
console.log(url.searchParams.get("userId"));   // 1  (ҳамеша сатр!)

Дархост ва ҷавоб

Дархост аз чор қисм, ҷавоб аз се қисм иборат аст. Ин схемаро дар хотир доред: вай барои фаҳмидани ҳама гуна ҳуҷҷатгузории API лозим аст.

Дархост (клиент → сервер)

Усул (чӣ кор кардан) · URL (дар куҷо) · сарлавҳаҳо (маълумоти хидматӣ) · бадан (маълумот, агар мефиристем).

Ҷавоб (сервер → клиент)

Статус (рақам: чӣ тавр гузашт) · сарлавҳаҳо (масалан, навъи маълумот) · бадан (худи маълумот, аксаран JSON).

Усулҳо: феъли дархост

Усул ба сервер мегӯяд, ки мо чиро иҷро кардан мехоҳем. Барои кор бо маълумот панҷ усули асосӣ ҳаст. Суроғаи онҳо метавонад якхела бошад — фақат феъл фарқ мекунад.

УсулЧӣ мекунадМисол аз ҳаётБадани дархост
GETМаълумот гирифтанМенюро диданне
POSTСабти нав сохтанФармоиши нав доданҳа
PUTСабтро пурра иваз карданФармоишро аз нав навиштанҳа
PATCHЯк қисми сабтро тағйир доданТанҳо суроғаи расониданро иваз карданҳа
DELETEСабтро нест карданФармоишро бекор карданне

Агар усул нишон дода нашавад, браузер GET-ро истифода мебарад. Имрӯз мо қариб ҳама вақт маълумот мегирем, ба усулҳои дигар дар қисми 05 мерасем.

Рамзҳои статус: рақаме, ки сервер аввал мегӯяд

Рақами аввали рамз — ин гурӯҳ аст. Агар гурӯҳҳоро дар хотир доред, 90%-и рамзҳоро бе маълумотнома мефаҳмед.

РамзГурӯҳМаъноМисолҳои маъмул
2xxМуваффақиятҲама чиз хуб шуд200 OK, 201 Created (сохта шуд), 204 No Content (муваффақият, аммо бадан нест)
3xxРавонакунӣДар ҷои дигар ҷустуҷӯ кунед301 саҳифа кӯчид, 304 чизе тағйир наёфт
4xxХатои клиентШумо чизеро нодуруст кардед400 дархости бад, 401 ворид нашудед, 403 ҳуқуқ нест, 404 ёфт нашуд, 429 хеле зуд-зуд
5xxХатои серверНазди онҳо вайрон шуд500 хатои дохилӣ, 503 сервер дастнорас аст

Сарлавҳаҳо: ёддоштҳои хидматӣ

Content-Type
Бадан кадом навъ аст. Барои JSON ин application/json аст. Ҳам дар дархост (чиро мефиристем), ҳам дар ҷавоб (чиро гирифтем) мешавад.
Accept
Дар дархост: «ман кадом формати ҷавобро мефаҳмам».
Authorization
Дар дархост: калид ё токен, ки тасдиқ мекунад шумо кистед. Бе он API-ҳои пӯшида бо 401 ҷавоб медиҳанд. Дар ин дарс он лозим нест — мо API-ҳои кушодаро мегирем.

JSON: забоне, ки API-ҳо бо он гап мезананд

Маълумот тавассути шабака ҳамчун матн мегузарад. Объектҳо ва массивҳоро ба матни формати JSON табдил медиҳанд ва баръакс: JSON.stringify(объект) → сатр, JSON.parse(сатр) → объект. Қоидаҳо аз JS сахттаранд: калидҳо ва сатрҳо танҳо дар нохунакҳои дукарата, бе шарҳҳо ва бе вергул дар охир.

Ба он ҷо ва баргашт · Ctrl + Enter
const student = { name: "Мадина", age: 17, courses: ["JS", "CSS"] };

const text = JSON.stringify(student);
console.log(text);                  // ин сатр аст
console.log(typeof text);

const back = JSON.parse(text);
console.log(back.name, back.courses.length);
Хатои маъмул

JSON-ро «мисли дар JavaScript» навиштан: бе нохунак дар калидҳо ё бо нохунакҳои яккарата. Чунин матнро JSON.parse қабул намекунад ва SyntaxError мепартояд.

Ин код хато медиҳад · Ctrl + Enter
const text = "{ name: 'Мадина' }";    // ✖ калид бе нохунак, сатр дар нохунакҳои яккарата

const student = JSON.parse(text);
console.log(student.name);

Муфассалтар хонед: learn.javascript.ru — Формати JSON · MDN — Шарҳи HTTP · MDN — Рамзҳои ҷавоби HTTP

Амал: мустаҳкам мекунем

Дар ин ҷо интернет ҳанӯз лозим нест: таҷзияи суроғаҳо, рамзҳои статус ва JSON-ро машқ мекунем.

ВАЗИФАИ 1.1

Таҷзияи суроға

осон

Аз суроғаи мағоза се сатр чоп кунед: номи хост, роҳ ва қимати параметри category.

Таҳрир кардан мумкин аст · Ctrl + Enter
const url = new URL("https://shop.example.tj/catalog/shoes?category=kids&page=2");

// url.hostname, url.pathname ва параметри category-ро чоп кунед
Натиҷаи интизоршаванда
shop.example.tj
/catalog/shoes
kids
Ишора 1

Хост ва роҳ дар хусусиятҳои url.hostname ва url.pathname ҷойгиранд.

Ишора 2

Параметрро бо усул мегирем: url.searchParams.get("category").

ВАЗИФАИ 1.2

Рамз чӣ маъно дорад

осон

Функсияи describeStatus(code)-ро анҷом диҳед: вай барои 200–299 «успех», барои 300–399 «перенаправление», барои 400–499 «ошибка клиента», барои 500–599 «ошибка сервера» ва барои ҳама чизи дигар «неизвестно»-ро бармегардонад.

Таҳрир кардан мумкин аст · Ctrl + Enter
function describeStatus(code) {
  // коди шумо
}

for (const code of [200, 201, 301, 404, 500, 99]) {
  console.log(code + ": " + describeStatus(code));
}
Натиҷаи интизоршаванда
200: успех
201: успех
301: перенаправление
404: ошибка клиента
500: ошибка сервера
99: неизвестно
Ишора 1

Занҷири if … else if-ро бо нобаробариҳо истифода баред: code >= 200 && code < 300.

Ишора 2

Шохаи охирини else «неизвестно»-ро бармегардонад — вай ҳам 99-ро, ҳам ҳар чизи аз 599 боло мегирад.

ВАЗИФАИ 1.3

Хаторо ёб: JSON-и вайроншуда

миёна

Сервер матн фиристод, аммо JSON.parse бо он меафтад. Матн-ро (бе ламс кардани кодҳои дигар) чунон ислоҳ кунед, ки JSON-и дуруст шавад.

Таҳрир кардан мумкин аст · Ctrl + Enter
const text = "{ name: 'Мадина', age: 17, active: true, }";

const student = JSON.parse(text);
console.log(student.name + " " + student.age);
Натиҷаи интизоршаванда
Мадина 17
Ишора 1

Дар JSON калидҳо ҳам дар нохунак навишта мешаванд ва нохунакҳо танҳо дукарата мебошанд. Дар дохили сатри оддии JS онҳоро бояд экран кард: \" — ё тамоми сатрро дар нохунакҳои яккарата гирифт.

Ишора 2

Хатои дигаре дар охир пинҳон шудааст: вергул баъд аз қимати охирин дар JSON манъ аст. Дуруст: '{"name": "Мадина", "age": 17, "active": true}'.

ВАЗИФАИ 1.4

Суроғаро бо параметрҳо ҷамъ кун

душвор

Функсияи buildUrl(base, params)-ро нависед, ки ба суроға параметрҳоро аз объект мечаспонад. URLSearchParams-ро истифода баред — вай худаш &-ро мегузорад ва ҳарфҳои русиро рамзгузорӣ мекунад.

Таҳрир кардан мумкин аст · Ctrl + Enter
function buildUrl(base, params) {
  // коди шумо
}

console.log(buildUrl("https://api.example.tj/products", { q: "плов", page: 2, limit: 10 }));
console.log(buildUrl("https://api.example.tj/products", {}));
Натиҷаи интизоршаванда
https://api.example.tj/products?q=%D0%BF%D0%BB%D0%BE%D0%B2&page=2&limit=10
https://api.example.tj/products
Ишора 1

new URLSearchParams(params).toString() объектро ба сатри намуди q=...&page=2 табдил медиҳад.

Ишора 2

Агар параметрҳо набошанд, сатр холӣ мешавад — он гоҳ аломати ? лозим нест: return query ? base + "?" + query : base;

02 fetch: дархости аввалин

fetch(url) — функсияи дарунсохти браузер барои дархостҳои HTTP. Ягон чизро пайваст кардан лозим нест. Вай промис бармегардонад (дарси 13), барои ҳамин бо он тавассути then ё, қулайтар, тавассути async / await кор мекунанд. Мекӯшем як вазифаро аз сервери таълимии jsonplaceholder гирем — вай махсус барои машқ кардан сохта шудааст:

Дархости аввалин · Ctrl + Enter
async function main() {
  const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
  const todo = await response.json();

  console.log(todo.title);
  console.log("выполнена?", todo.completed);
}

main();

Сатрҳо кам аст, аммо дар ин ҷо ду await ҳаст ва ин тасодуф нест. Биёед фаҳмем, барои чӣ.

  1. fetch(url) дархостро мефиристад. Промис ҳамин ки оғози ҷавоб — статус ва сарлавҳаҳо — расад, иҷро мешавад.
  2. await ба мо объекти response-ро медиҳад — ин «лифофа» аст: дар он статус ва сарлавҳаҳо ҳастанд, бадан бошад ҳанӯз дар роҳи шабака буда метавонад.
  3. response.json() баданро то охир мехонад ва матни JSON-ро ба объект табдил медиҳад. Ин ҳам промис аст — барои ҳамин await-и дуюм.
Қиёс аз ҳаёт

Шумо аз нонвойхона расониданро фармоиш додед. Аввал курйер занг мезанад: «Фармоиш қабул шуд, меравам» — ин response бо статус аст. Баъд ӯ бо қуттӣ назди шумо мебарояд — ин response.json() аст. Занг ва қуттӣ дар вақтҳои гуногун меоянд, барои ҳамин ду бор интизор шудан лозим мешавад.

Дар response чӣ ҳаст

response.status
Рақам — рамзи статус: 200, 404, 500…
response.ok
true, агар статус аз 200 то 299 бошад. Судмандтарин санҷиш — ба он дар қисми 04 бармегардем.
response.headers
Сарлавҳаҳои ҷавоб. Бо усули get хонда мешаванд: response.headers.get("content-type").
response.json()
Баданро ҳамчун JSON хондан → объект ё массив мегирем.
response.text()
Баданро ҳамчун матни оддӣ хондан (қулай аст, агар на JSON омада бошад).
Ба «лифофа» менигарем · Ctrl + Enter
async function main() {
  const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");

  console.log("статус:", response.status);
  console.log("ok:", response.ok);
  console.log("тип данных:", response.headers.get("content-type"));
}

main();

Ҳамин чиз тавассути then

Варианти бе async / await низ дар кодҳои бегона вомехӯрад — шумо бояд онро шиносед. Маъно ҳамон аст, фақат дохилшавӣ дигар аст:

fetch + then · Ctrl + Enter
fetch("https://jsonplaceholder.typicode.com/todos/1")
  .then((response) => response.json())
  .then((todo) => {
    console.log("Задача:", todo.title);
  });
Хатои маъмул

await-ро пеш аз fetch ё пеш аз response.json() фаромӯш кардан. Он гоҳ дар тағйирёбанда на маълумот, балки промис мемонад ва ҳама муроҷиат ба майдонҳо undefined медиҳанд.

Хато: await-и дуюм нест · Ctrl + Enter
async function main() {
  const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
  const todo = response.json();     // ✖ await-ро фаромӯш кардем — ин промис аст, на объект

  console.log(todo.title);          // undefined
}

main();

Муфассалтар хонед: learn.javascript.ru — Fetch · MDN — Истифодаи Fetch

Амал: мустаҳкам мекунем

Ин вазифаҳо ба jsonplaceholder мераванд: баъд аз иҷро як сония интизор шавед.

ВАЗИФАИ 2.1

Номи аввалин

осон

Постро бо рақами 1 аз суроғаи https://jsonplaceholder.typicode.com/posts/1 бор кунед ва майдони userId-и онро, баъд id-ро чоп кунед.

Таҳрир кардан мумкин аст · Ctrl + Enter
async function main() {
  // дархост, response.json(), чоп
}

main();
Натиҷаи интизоршаванда
1
1
Ишора 1

Ду қадам: const response = await fetch(…), баъд const post = await response.json().

Ишора 2

Баъд аз ин: console.log(post.userId); console.log(post.id);

ВАЗИФАИ 2.2

Назар ба лифофа

осон

https://jsonplaceholder.typicode.com/users/1-ро дархост кунед. Бе хондани бадан чоп кунед: статус, ok ва ҷавоб ба саволи «оё сарлавҳаи content-type калимаи json-ро дорад» (усули сатри includes).

Таҳрир кардан мумкин аст · Ctrl + Enter
async function main() {
  // fetch, баъд се сатри чоп
}

main();
Натиҷаи интизоршаванда
200
true
true
Ишора 1

Хусусиятҳои response.status ва response.ok бе await хонда мешаванд — онҳо аллакай расидаанд.

Ишора 2

console.log(response.headers.get("content-type").includes("json"));

ВАЗИФАИ 2.3

Тартибро пешгӯӣ кун: дархост «дар паси парда» мегузарад

миёна

Нишонаҳо ба массив бо кадом тартиб меафтанд? Дарси 13-ро ба ёд оред: то даме ки fetch ҷавобро интизор аст, JavaScript дар ҷояш намеистад. Пешгӯиро ба prediction ворид кунед ва иҷро намоед.

Таҳрир кардан мумкин аст · Ctrl + Enter
const actual = [];
const log = (label) => actual.push(label);

async function main() {
  log("A");
  const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
  log("B");
  await response.json();
  log("C");
}

main();
log("D");

const prediction = [];   // пешгӯии шумо: тартиби нишонаҳо

// --- санҷиш, тағйир надиҳед ---
setTimeout(() => console.log(actual.join(" ") === prediction.join(" ") ? "Верно!" : "Не угадали, подумайте ещё"), 3000);
Натиҷаи интизоршаванда
Верно!
Ишора 1

Функсияи main то аввалин await синхронӣ кор мекунад: нишонаи A фавран гузошта мешавад. Баъд вай «хоб меравад» ва идоракунӣ ба берун бармегардад — ба нишонаи D.

Ишора 2

Баъд аз D код ҷавобро интизор мешавад: аввал баъд аз await-и якум идома меёбад (B), баъд баъд аз дуюм (C). Натиҷа: A D B C.

ВАЗИФАИ 2.4

Ду боркунии вобаста

миёна

Вазифаи /todos/1 майдони userId дорад — рақами муаллиф. Вазифаро бор кунед, баъд муаллифро аз суроғаи /users/ + userId гиред ва чоп кунед: Задача «название» у имя. Суроғаи сервер: https://jsonplaceholder.typicode.com.

Таҳрир кардан мумкин аст · Ctrl + Enter
const API = "https://jsonplaceholder.typicode.com";

async function main() {
  // 1) вазифаи 1-ро бор кунед
  // 2) корбарро аз рӯи todo.userId бор кунед
  // 3) сатрро чоп кунед
}

main();
Натиҷаи интизоршаванда
Задача «delectus aut autem» у Leanne Graham
Ишора 1

Суроғаи дархости дуюмро аз маълумоти якум ҷамъ мекунем: `${API}/users/${todo.userId}`.

Ишора 2

Ҳар дархост — ин ҷуфт аст: const r = await fetch(…); const data = await r.json();. Чунин ҷуфтҳо назди шумо ду то мешавад.

03 Бадани ҷавоб: json(), text() ва параметрҳои дархост

Серверҳо маълумотро дар ду намуд медиҳанд: як объект (/users/1) ва рӯйхат (/users — массив). Баъд аз response.json() шумо объектҳо ва массивҳои оддии JavaScript мегиред ва бо онҳо шумо аллакай кор карда метавонед: map, filter, деструктуризатсия, ?..

Рӯйхат: массиви объектҳо · Ctrl + Enter
const API = "https://jsonplaceholder.typicode.com";

async function main() {
  const response = await fetch(API + "/users");
  const users = await response.json();

  console.log("Пользователей:", users.length);

  const names = users.slice(0, 3).map((user) => user.name);
  console.log(names.join(", "));
}

main();

Маълумоти дохилшуда

Ҷавобҳои воқеӣ қариб ҳамеша дохилшуда мебошанд: корбар суроға дорад, суроға — шаҳр. Деструктуризатсия аз дарси 7 дар ин ҷо хеле бамаврид аст:

Дохилшударо мегирем · Ctrl + Enter
async function main() {
  const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
  const { name, email, address: { city } } = await response.json();

  console.log(`${name}, ${city}, ${email}`);
}

main();

Параметрҳои дархост: танҳо лозимаро металабем

Ҳамаро пайдарпай зеркашӣ кардан — исрофкорӣ аст. Аксари API-ҳо параметрҳоро баъд аз аломати ? мефаҳманд: филтрҳо, маҳдудиятҳо, ҷустуҷӯ. Дар jsonplaceholder, масалан, ?_limit=3 танҳо се сабтро бармегардонад, ?userId=2 бошад — танҳо сабтҳои корбари дуюмро.

Филтр дар тарафи сервер · Ctrl + Enter
async function main() {
  const url = "https://jsonplaceholder.typicode.com/todos?userId=2&_limit=3";
  const todos = await (await fetch(url)).json();

  console.log("Получили:", todos.length);
  console.log("Все от пользователя 2:", todos.every((t) => t.userId === 2));
}

main();

Сатри await (await fetch(url)).json() — навишти фушурдаи ду қадам аст. Душвортар хонда мешавад, барои ҳамин ҳоло беҳтар аст қадам ба қадам нависед.

json() ё text()?

json() дар вуруд JSON-и дурустро интизор аст. Агар сервер саҳифаи HTML бо хато ё ҷавоби холӣ фиристад, json() SyntaxError мепартояд. text() бошад ҳамеша матн бармегардонад — онро нишон додан ё ба лог навиштан мумкин аст. Барои машқ кардан бе интернет мо «ҷавоби қалбакӣ» сохта метавонем: конструктори new Response(матн) айнан ҳамон объектеро месозад, ки аз сервери воқеӣ меояд.

Ҷавоби қалбакӣ барои машқ · Ctrl + Enter
async function main() {
  const response = new Response(JSON.stringify({ city: "Душанбе", temp: 21 }));

  const data = await response.json();
  console.log(data.city + ": " + data.temp);
}

main();
Хатои маъмул

Бадани ҷавобро танҳо як маротиба хондан мумкин аст. text()-ро даъват кардед — баъд json() дигар кор намекунад: маълумот «нӯшида шуд». Баданро як бор хонед ва натиҷаро дар тағйирёбанда нигоҳ доред.

Ин код хато медиҳад · Ctrl + Enter
async function main() {
  const response = new Response(JSON.stringify({ city: "Душанбе" }));

  const text = await response.text();   // бадан хонда шуд
  const data = await response.json();   // ✖ бори дуюм мехонем

  console.log(text, data);
}

main();

Муфассалтар хонед: learn.javascript.ru — Fetch: хондани ҷавоб · MDN — Response.json()

Амал: мустаҳкам мекунем

ВАЗИФАИ 3.1

Се вазифаи аввал

осон

https://jsonplaceholder.typicode.com/todos?_limit=3-ро бор кунед ва номи вазифаҳоро бо рақамҳо чоп кунед: 1. название, 2. название…

Таҳрир кардан мумкин аст · Ctrl + Enter
async function main() {
  // дархост, json(), давра бо рақамҳо
}

main();
Натиҷаи интизоршаванда
1. delectus aut autem
2. quis ut nam facilis et officia qui
3. fugiat veniam minus
Ишора 1

Ҷавоб — массив аст. Онро тавассути forEach((todo, index) => …) тай кунед.

Ишора 2

Рақами сатр — index + 1: console.log(`${index + 1}. ${todo.title}`).

ВАЗИФАИ 3.2

Корти корбар

миёна

/users/1-ро бор кунед ва сатри намуди Leanne Graham — Gwenborough (Bret)-ро чоп кунед: ном, шаҳр аз address-и дохилшуда ва дар қавс — username.

Таҳрир кардан мумкин аст · Ctrl + Enter
async function main() {
  const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
  // деструктуризатсия ва чоп
}

main();
Натиҷаи интизоршаванда
Leanne Graham — Gwenborough (Bret)
Ишора 1

Майдони дохилшударо ҳамин тавр гирифтан мумкин аст: const { name, username, address: { city } } = await response.json();

Ишора 2

Сатрро бо нохунакҳои қолабӣ ҷамъ мекунем: `${name} — ${city} (${username})`. Хати дарозро аз шарт нусха кунед.

ВАЗИФАИ 3.3

Чанд кор иҷро шудааст

миёна

Ҳамаи вазифаҳои корбари аввалро бор кунед: /todos?userId=1. Чоп кунед, ки ҳамагӣ чанд вазифа ҳаст ва аз онҳо чандтоаш иҷро шудааст (completed === true).

Таҳрир кардан мумкин аст · Ctrl + Enter
async function main() {
  // дархост бо параметри userId=1
  // ҳамагӣ ва иҷрошуда
}

main();
Натиҷаи интизоршаванда
Всего: 20
Выполнено: 11
Ишора 1

Суроға: "https://jsonplaceholder.typicode.com/todos?userId=1". Дарозии массив — todos.length.

Ишора 2

Иҷрошудаҳо: todos.filter((todo) => todo.completed).length.

ВАЗИФАИ 3.4

Хаторо ёб: бадан ду бор хонда шуд

миёна

Барномасоз мехост аввал матни «хом»-и ҷавобро барои лог нигоҳ дорад, баъд аз он маълумот гирад. Код меафтад. Онро чунон ислоҳ кунед, ки бадан як маротиба хонда шавад: аввал text(), объектро бошад тавассути JSON.parse гиред.

Таҳрир кардан мумкин аст · Ctrl + Enter
async function main() {
  const response = new Response(JSON.stringify({ city: "Душанбе", temp: 21 }));

  const raw = await response.text();
  console.log("Длина текста:", raw.length);

  const data = await response.json();
  console.log(data.city + ": " + data.temp + "°C");
}

main();
Натиҷаи интизоршаванда
Длина текста: 28
Душанбе: 21°C
Ишора 1

Мушкил дар сатри await response.json() аст — бадан аллакай бо усули text() хонда шудааст.

Ишора 2

Онро бо const data = JSON.parse(raw); иваз кунед — матн назди мо аллакай дар тағйирёбандаи raw ҳаст.

04 Хатоҳо: 404 — хатои fetch нест

Ин барои навомӯзон ғайричашмдоштарин ҷост. Дархост метавонад ду навъи комилан гуногуни ноком дошта бошад — ва fetch ба онҳо гуногун муносибат мекунад.

Қиёс аз ҳаёт

Шумо бо маршрутка ба Рӯдакӣ меравед. Хатои шабакавӣ — маршрутка дар роҳ вайрон шуд ва шумо умуман нарасидед (интернет нест, суроғаи сервер нодуруст, сервер хомӯш аст). Ҷавоб бо рамзи 404 ё 500 — шумо расидед, ба мағоза даромадед, фурӯшанда бошад мегӯяд «чунин мол нест» ё «имрӯз мо пӯшидаем». Шумо бо сервер алоқа кардед, вай ҷавоб дод — фақат на он чизе, ки шумо интизор будед.

Вазъиятfetch чӣ мекунадЧӣ тавр фаҳмидан
Шабака нест, сервер дастнорас аст, суроға нодурустПромис рад мешавад (хатои TypeError)catch кор мекунад
Сервер 404, 500 ва ғайра ҷавоб додПромис бомуваффақият иҷро мешавад!response.ok ё response.status-ро санҷед

Бинед: дархости вазифаи вуҷуднадошта хато напартофт. catch хомӯш аст, ok бошад ба false баробар аст.

404 ба catch намеафтад · Ctrl + Enter
async function main() {
  try {
    const response = await fetch("https://jsonplaceholder.typicode.com/todos/99999");
    console.log("запрос дошёл до сервера");
    console.log("статус:", response.status, "ok:", response.ok);
  } catch (error) {
    console.log("сюда мы не попадём");
  }
}

main();

Схемаи дуруст: ok-ро месанҷем ва хаторо худамон мепартоем

Барои он ки ҳарду ноком дар як ҷой коркард шаванд, «статуси бад»-ро ба хатои ҳақиқӣ табдил медиҳем:

Қолабе, ки шумо ҳамеша менависед · Ctrl + Enter
async function loadTodo(id) {
  const response = await fetch("https://jsonplaceholder.typicode.com/todos/" + id);

  if (!response.ok) {
    throw new Error("HTTP " + response.status);   // 404 → хатои ҳақиқӣ
  }
  return response.json();
}

async function main() {
  for (const id of [1, 99999]) {
    try {
      const todo = await loadTodo(id);
      console.log("Нашли:", todo.title);
    } catch (error) {
      console.log("Ошибка:", error.message);
    }
  }
}

main();

Хатои шабакавӣ: сервер умуман нест

Вақте дархост ба сервер расида натавонист, fetch промисро рад мекунад ва catch хатои навъи TypeError мегирад. Барои тақлид кардани ин суроғаеро мегирем, ки яқинан вуҷуд надорад (минтақаи .invalid барои суроғаҳои «вуҷуднадошта» ҷудо карда шудааст):

Сервер вуҷуд надорад · Ctrl + Enter
async function main() {
  try {
    await fetch("https://no-such-server.invalid/data");
    console.log("не дойдём досюда");
  } catch (error) {
    console.log("Сеть недоступна. Тип ошибки:", error.name);
  }
}

main();

Матни худи хато дар браузерҳои гуногун фарқ мекунад (дар Chrome — Failed to fetch, дар Safari — Load failed), барои ҳамин ба error.message такя кардан мумкин нест. Боэътимодтар аст ба error.name нигаред ё оддӣ ба корбар матни фаҳмои худатонро нишон диҳед.

Сабаби дигари «Failed to fetch» — CORS

Браузер ба саҳифаҳо иҷозат намедиҳад ҷавобҳои серверҳои бегонаро хонанд, агар онҳо ошкоро иҷозат надода бошанд (сарлавҳаи Access-Control-Allow-Origin). API-ҳои таълимии оммавӣ ба ҳама иҷозат медиҳанд, барои ҳамин назди мо ҳама чиз кор мекунад. Аммо вақте сервери «пӯшида»-ро дархост кунед, дар консол паёми сурх дар бораи CORS пайдо мешавад, fetch бошад ҳамон хатои шабакавиро медиҳад. Ин хатои коди шумо нест: соҳиби сервер бояд дархостҳоро аз сайти шумо иҷозат диҳад. Муфассалтар дар дарсҳои оянда таҳлил мекунем.

Вақте бадан JSON нест

Нохушии сеюм: сервер ҷавоб дод, аммо дар бадан JSON нест (масалан, саҳифаи HTML «Хидмат муваққатан дастнорас аст»). Он гоҳ response.json() SyntaxError мепартояд. Дар ҷавоби қалбакӣ месанҷем:

Бадан JSON нест · Ctrl + Enter
async function main() {
  const response = new Response("<html>Сервис временно недоступен</html>", { status: 503 });

  try {
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.log("Не удалось разобрать JSON. Тип ошибки:", error.name);
  }
}

main();
Хатои маъмул

Фавран response.json()-ро иҷро кардан ва ба беҳтарин умедвор будан. Барои ҷавоби 404 бо бадани холӣ ({}) код «кор мекунад» ва ба ҷои маълумот undefined медиҳад — сабаби воқеӣ (сабт ёфт нашуд) бошад ношинохта мемонад.

Хато: санҷиши ok нест · Ctrl + Enter
async function main() {
  const response = await fetch("https://jsonplaceholder.typicode.com/todos/99999");
  const todo = await response.json();      // ✖ статус 404, аммо хато нест

  console.log("Название задачи:", todo.title);   // undefined
}

main();

finally: «Боркунӣ…»-ро дар ҳар натиҷа нест мекунем

Блоки finally ҳам баъд аз муваффақият, ҳам баъд аз хато иҷро мешавад. Ин ҷои беҳтарин барои пинҳон кардани нишондиҳандаи боркунӣ ё аз нав фаъол кардани тугма аст (мо инро дар дарси 13 мекардем).

Муфассалтар хонед: learn.javascript.ru — Fetch: response.ok · MDN — Response.ok · MDN — CORS

Амал: мустаҳкам мекунем

ВАЗИФАИ 4.1

Статуси вазифаи вуҷуднадошта

осон

https://jsonplaceholder.typicode.com/todos/99999-ро дархост кунед ва дар як сатр статус ok-ро чоп кунед — яъне рамзи ҷавоб ва қимати response.ok-ро бо фосила. Баданро хондан лозим нест.

Таҳрир кардан мумкин аст · Ctrl + Enter
async function main() {
  // fetch ва як сатри чоп
}

main();
Натиҷаи интизоршаванда
404 false
Ишора 1

const response = await fetch(…) кифоя аст. Баданро хондан лозим нест — статус аллакай дар response ҳаст.

Ишора 2

console.log(response.status, response.ok); — console.log худаш байни аргументҳо фосила мегузорад.

ВАЗИФАИ 4.2

Боркунӣ бо санҷиш

миёна

loadTodo(id)-ро анҷом диҳед: агар ҷавоб ok набошад — new Error("HTTP " + response.status)-ро бипартоед, вагарна маълумотро баргардонед. Баъд давра бояд номи вазифаи 1 ва хатои 99999-ро чоп кунад.

Таҳрир кардан мумкин аст · Ctrl + Enter
async function loadTodo(id) {
  const response = await fetch("https://jsonplaceholder.typicode.com/todos/" + id);
  // санҷиши ok ва баргардонидани маълумот
}

async function main() {
  for (const id of [1, 99999]) {
    try {
      const todo = await loadTodo(id);
      console.log(todo.title);
    } catch (error) {
      console.log("Ошибка: " + error.message);
    }
  }
}

main();
Натиҷаи интизоршаванда
delectus aut autem
Ошибка: HTTP 404
Ишора 1

Шарт: if (!response.ok) { throw new Error(…); } — пеш аз баргардонидани маълумот.

Ишора 2

Баргардонидан: return response.json(); — функсияи async худаш натиҷаро ба промис мепечонад.

ВАЗИФАИ 4.3

Сервер ҷавоб намедиҳад

осон

Дархостро ба https://no-such-server.invalid/data фиристед. Хаторо дастгир кунед ва Сеть недоступна: ТипОшибки-ро чоп кунед, ба ҷои «ТипОшибки» error.name-ро гузошта.

Таҳрир кардан мумкин аст · Ctrl + Enter
async function main() {
  // try / catch дар атрофи fetch
}

main();
Натиҷаи интизоршаванда
Сеть недоступна: TypeError
Ишора 1

await fetch(…)-ро ба try печонед, дар catch (error) бошад паёмро чоп кунед.

Ишора 2

console.log("Сеть недоступна: " + error.name);

ВАЗИФАИ 4.4

Хондани бехатари JSON

душвор

readData(response)-ро нависед: агар статус ok набошад, вай сатри "Ошибка сервера: " + status-ро бармегардонад. Агар статус хуб бошад, аммо бадан JSON набошад, "Ответ не JSON"-ро бармегардонад. Вагарна — худи маълумотро. Ҷавобҳо қалбакианд (бе интернет), барои ҳамин натиҷа фавриист.

Таҳрир кардан мумкин аст · Ctrl + Enter
async function readData(response) {
  // коди шумо
}

async function main() {
  const answers = [
    new Response(JSON.stringify({ city: "Худжанд" })),
    new Response("{}", { status: 404 }),
    new Response("<html>Привет</html>"),
    new Response("Сервис недоступен", { status: 503 }),
  ];

  for (const response of answers) {
    const result = await readData(response);
    console.log(typeof result === "string" ? result : result.city);
  }
}

main();
Натиҷаи интизоршаванда
Худжанд
Ошибка сервера: 404
Ответ не JSON
Ошибка сервера: 503
Ишора 1

Аввал if (!response.ok) return …. Баргашти барвақт аз дохилшавии зиёдатӣ халос мекунад.

Ишора 2

Таҷзияи JSON-ро ба try { return await response.json(); } catch { return "Ответ не JSON"; } печонед — бе await пеш аз response.json() хато ба catch намеафтад.

ВАЗИФАИ 4.5

Се боркунӣ бо finally

душвор

Вазифаҳоро бо рақамҳои 1, 99999 ва 2 ба навбат бор кунед. Барои ҳар кадом: Загружаем #id-ро чоп кунед; ҳангоми муваффақият — номро, ҳангоми хато — Ошибка: HTTP 404 (рамз аз ҷавоб); дар ҳар сурат — сатри — готово-ро (тавассути finally).

Таҳрир кардан мумкин аст · Ctrl + Enter
async function loadTodo(id) {
  const response = await fetch("https://jsonplaceholder.typicode.com/todos/" + id);
  if (!response.ok) {
    throw new Error("HTTP " + response.status);
  }
  return response.json();
}

async function main() {
  for (const id of [1, 99999, 2]) {
    // try / catch / finally
  }
}

main();
Натиҷаи интизоршаванда
Загружаем #1
delectus aut autem
— готово
Загружаем #99999
Ошибка: HTTP 404
— готово
Загружаем #2
quis ut nam facilis et officia qui
— готово
Ишора 1

Сатри «Загружаем»-ро пеш аз try чоп кунед. Дар дохили давра ҳар се блок лозим аст: try, catch, finally.

Ишора 2

try { const todo = await loadTodo(id); console.log(todo.title); } catch (error) { console.log("Ошибка: " + error.message); } finally { console.log("— готово"); }

05 POST, PUT, DELETE: маълумот мефиристем

Барои сохтан ё тағйир додани сабт, аргументи дуюми fetch — объекти танзимот аст. Дар он се калиди асосӣ ҳаст: method, headers ва body.

method: "POST"headers: { "Content-Type": "application/json" }body: JSON.stringify(data)
Се калиди танзимот: чӣ мекунем, баданро чӣ тавр тавсиф мекунем ва худи бадан (ҳамеша сатр)
Дар бораи сервери таълимии мо

jsonplaceholder — сервери «ҳамчун гӯӣ»: вай POST, PUT ва DELETE-ро қабул мекунад, мисли воқеӣ ҷавоб медиҳад, аммо ҳеҷ чизро нигоҳ намедорад. Пост сохтед — аммо дар дархости оянда он нест. Барои омӯзиш ин беҳтарин аст: ҳеҷ чизро вайрон кардан мумкин нест. Серверҳои воқеӣ, албатта, маълумотро ба ёд мегиранд.

POST: пост месозем · Ctrl + Enter
async function main() {
  const response = await fetch("https://jsonplaceholder.typicode.com/posts", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ title: "Мой первый пост", body: "Салом, мир!", userId: 1 }),
  });

  const created = await response.json();

  console.log("статус:", response.status);   // 201 — Created
  console.log("id:", created.id);            // сервер рақам дод
  console.log("заголовок:", created.title);  // ва он чиро, ки фиристодем, баргардонд
}

main();
  1. method: "POST" — ба сервер хабар медиҳем, ки мехоҳем сабт созем.
  2. Content-Type: application/json — огоҳ мекунем: «дар бадан JSON ҳаст». Бе ин сервер баданро нафаҳмидан метавонад.
  3. JSON.stringify(...) — бадани дархост бояд сатр бошад, объектро бевосита фиристодан мумкин нест.
  4. Дар ҷавоб сервер 201 Created ва сабти сохташударо — бо id-и нав — бармегардонад.

PUT, PATCH ва DELETE

Ҳамон танзимот, усули дигар. Суроға акнун ба сабти мушаххас ишора мекунад: /posts/1.

PUT, PATCH ва DELETE · Ctrl + Enter
const API = "https://jsonplaceholder.typicode.com";
const json = { "Content-Type": "application/json" };

async function main() {
  // PUT — сабтро пурра иваз кардан
  let response = await fetch(API + "/posts/1", {
    method: "PUT",
    headers: json,
    body: JSON.stringify({ title: "Новый заголовок", body: "новый текст", userId: 1 }),
  });
  console.log("PUT:", response.status, (await response.json()).title);

  // PATCH — танҳо як майдонро тағйир додан
  response = await fetch(API + "/posts/1", {
    method: "PATCH",
    headers: json,
    body: JSON.stringify({ title: "Только заголовок" }),
  });
  console.log("PATCH:", response.status, (await response.json()).title);

  // DELETE — нест кардан, бадан лозим нест
  response = await fetch(API + "/posts/1", { method: "DELETE" });
  console.log("DELETE:", response.status);
}

main();
Хатои маъмул

Объектро бе JSON.stringify ва бе Content-Type фиристодан. Браузер объектро ба сатри "[object Object]" табдил медиҳад ва маълумот дар роҳ гум мешавад. Сервер ҳангоми ин метавонад «бомуваффақият» (201) ҷавоб диҳад — фақат бо сабти холӣ. Ҳамеша санҷед, ки сервер чӣ баргардонд, на танҳо статусро.

Дар асл ба body чӣ меравад · Ctrl + Enter
const data = { title: "Салом" };

console.log("без stringify:", String(data));         // ✖ маълумотро гум кардем
console.log("со stringify:", JSON.stringify(data));  // ✔ JSON-и дуруст

Муфассалтар хонед: learn.javascript.ru — Fetch: дархостҳои POST · MDN — Усулҳои HTTP

Амал: мустаҳкам мекунем

ВАЗИФАИ 5.1

Сабти нав дар блог

осон

POST-ро ба https://jsonplaceholder.typicode.com/posts бо маълумоти { title: "Салом", body: "Первый пост", userId: 1 } фиристед. Рамзи статус ва рақамеро, ки сервер дод, чоп кунед.

Таҳрир кардан мумкин аст · Ctrl + Enter
async function main() {
  // fetch бо method, headers ва body
}

main();
Натиҷаи интизоршаванда
Статус: 201
id: 101
Ишора 1

Аргументи дуюми fetch: { method: "POST", headers: { "Content-Type": "application/json" }, body: … }.

Ишора 2

Ба body JSON.stringify({ title: "Салом", body: "Первый пост", userId: 1 })-ро гузоред. Рақам — дар майдони id-и ҷавоб.

ВАЗИФАИ 5.2

Фабрикаи танзимот

миёна

Барои он ки дар ҳар дархост як чизро такрор нанависем, функсияи makeOptions(method, data)-ро нависед. Вай объекти танзимотро бо усул, сарлавҳаи Content-Type ва бадани JSON бармегардонад. Интернет лозим нест — мо оддӣ мебинем, ки чӣ шуд.

Таҳрир кардан мумкин аст · Ctrl + Enter
function makeOptions(method, data) {
  // коди шумо
}

console.log(JSON.stringify(makeOptions("POST", { title: "Салом" })));
console.log(JSON.stringify(makeOptions("PUT", { id: 7 })));
Натиҷаи интизоршаванда
{"method":"POST","headers":{"Content-Type":"application/json"},"body":"{\"title\":\"Салом\"}"}
{"method":"PUT","headers":{"Content-Type":"application/json"},"body":"{\"id\":7}"}
Ишора 1

Тартиби калидҳо барои санҷиш муҳим аст: аввал method, баъд headers, баъд body.

Ишора 2

return { method, headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) };

ВАЗИФАИ 5.3

Постро иваз мекунем

миёна

Дархости PUT-ро ба https://jsonplaceholder.typicode.com/posts/1 бо маълумоти { title: "Новый заголовок", body: "текст", userId: 1 } фиристед. Статусро, баъд title ва id-ро аз ҷавоб чоп кунед.

Таҳрир кардан мумкин аст · Ctrl + Enter
async function main() {
  // дархости PUT
}

main();
Натиҷаи интизоршаванда
200
Новый заголовок
1
Ишора 1

Фарқ аз POST танҳо дар method: "PUT" ва дар суроға аст: акнун вай ба сабти /posts/1 ишора мекунад.

Ишора 2

Сервер он чиро, ки фиристодед, плюс id-ро бармегардонад: console.log(response.status); console.log(data.title); console.log(data.id);

ВАЗИФАИ 5.4

Постро нест мекунем

осон

DELETE-ро ба https://jsonplaceholder.typicode.com/posts/1 фиристед ва статуси ҷавоб ва холӣ будани онро (Object.keys(data).length === 0) чоп кунед.

Таҳрир кардан мумкин аст · Ctrl + Enter
async function main() {
  // дархости DELETE
}

main();
Натиҷаи интизоршаванда
200
true
Ишора 1

Барои DELETE { method: "DELETE" } кифоя аст — бадан ва сарлавҳаҳо лозим нестанд.

Ишора 2

Ҷавобро хонед: const data = await response.json(); — сервер объекти холии {}-ро бармегардонад.

ВАЗИФАИ 5.5

Хаторо ёб: маълумот гум шуд

миёна

Дархост 201 бармегардонад, аммо дар ҷавоб сарлавҳаи пост нест: created.title ба undefined баробар аст. Ёбед, ки дар танзимот чӣ намерасад ва ислоҳ кунед.

Таҳрир кардан мумкин аст · Ctrl + Enter
async function main() {
  const response = await fetch("https://jsonplaceholder.typicode.com/posts", {
    method: "POST",
    body: { title: "Салом", body: "Первый пост", userId: 1 },
  });

  const created = await response.json();
  console.log(response.status);
  console.log(created.title);
}

main();
Натиҷаи интизоршаванда
201
Салом
Ишора 1

Бадани дархост бояд сатри JSON бошад, объект бошад ба "[object Object]" табдил меёбад.

Ишора 2

headers: { "Content-Type": "application/json" }-ро илова кунед ва объектро ба JSON.stringify(…) печонед.

06 Печонандаи худии api.js-ро месозем

Бинед, мо аллакай чанд кодҳои такроршаванда навиштем: суроғаи сервер, санҷиши ok, сарлавҳаҳо, JSON.stringify, response.json(). Дар лоиҳаи калон дархостҳо даҳҳо мебошанд. Роҳи ҳал — як функсияи печонанда, ки ҳамаи инро ба ҷои шумо иҷро мекунад. Ин аст артефакти дарси шумо: файли api.js. Онро қадам ба қадам месозем ва дар ҳар қадам код кор мекунад.

Қадами 1. Як функсия ба ҷои нусхабардорӣ

Суроғаи серверро ба константа мебарем ва ҷамъ кардани суроғаи пурраро аз роҳ меомӯзем.

api.js · қадами 1 · Ctrl + Enter
const BASE_URL = "https://jsonplaceholder.typicode.com";

async function request(path) {
  const response = await fetch(BASE_URL + path);
  return response.json();
}

async function main() {
  const todo = await request("/todos/1");
  console.log(todo.title);
}

main();

Қадами 2. Санҷиши ok ва хато бо статус

Асосиро илова мекунем: статуси бад ба хато табдил меёбад. Ҳамзамон рамзи статусро рост ба хато мегузорем — барои коди даъваткунанда он судманд аст (масалан, ба ҷои «Хато» «Ёфт нашуд»-ро нишон додан).

api.js · қадами 2 · Ctrl + Enter
const BASE_URL = "https://jsonplaceholder.typicode.com";

async function request(path) {
  const response = await fetch(BASE_URL + path);

  if (!response.ok) {
    const error = new Error("HTTP " + response.status);
    error.status = response.status;      // рамзро ба хато ба ёд мемонем
    throw error;
  }
  return response.json();
}

async function main() {
  try {
    await request("/todos/99999");
  } catch (error) {
    console.log(error.message, "| статус в ошибке:", error.status);
  }
}

main();

Қадами 3. Дастгирии POST ва усулҳои дигар

Аргументи дуюми options-ро қабул мекунем. Агар body дода шавад — худамон JSON.stringify мекунем ва сарлавҳаро мегузорем. Акнун бадан ҳамеша дуруст фиристода мешавад.

api.js · қадами 3 · Ctrl + Enter
const BASE_URL = "https://jsonplaceholder.typicode.com";

async function request(path, { method = "GET", body } = {}) {
  const options = { method, headers: {} };

  if (body !== undefined) {
    options.headers["Content-Type"] = "application/json";
    options.body = JSON.stringify(body);
  }

  const response = await fetch(BASE_URL + path, options);

  if (!response.ok) {
    const error = new Error("HTTP " + response.status);
    error.status = response.status;
    throw error;
  }
  return response.json();
}

async function main() {
  const post = await request("/posts", { method: "POST", body: { title: "Салом", userId: 1 } });
  console.log("создан пост номер", post.id);
}

main();

Навишти { method = "GET", body } = {} — ин деструктуризатсияи параметр бо қиматҳои пешфарз аст (дарси 7). Ба шарофати = {} функсияро бе аргументи дуюм ҳам даъват кардан мумкин аст.

Қадами 4. Таймаут: абадӣ интизор намешавем

Агар сервер овезон шавад, корбар то беохир ба «Боркунӣ…» менигарад. Барои ҳамин маҳдудияти вақтро илова мекунем. Барои ин fetch «тугмаи бекор кардан» дорад — AbortController: controller.abort()-ро даъват мекунем ва дархост бо хатои AbortError қатъ мешавад.

api.js · қадами 4 · Ctrl + Enter
const BASE_URL = "https://jsonplaceholder.typicode.com";

async function request(path, { method = "GET", body, timeout = 8000 } = {}) {
  const options = { method, headers: {} };

  if (body !== undefined) {
    options.headers["Content-Type"] = "application/json";
    options.body = JSON.stringify(body);
  }

  const controller = new AbortController();
  options.signal = controller.signal;
  const timer = setTimeout(() => controller.abort(), timeout);   // баъд аз timeout мс — бекор кардан

  try {
    const response = await fetch(BASE_URL + path, options);

    if (!response.ok) {
      const error = new Error("HTTP " + response.status);
      error.status = response.status;
      throw error;
    }
    return await response.json();
  } catch (error) {
    if (error.name === "AbortError") {
      throw new Error("сервер не ответил за " + timeout + " мс");
    }
    throw error;
  } finally {
    clearTimeout(timer);               // таймер акнун лозим нест
  }
}

async function main() {
  try {
    await request("/todos/1", { timeout: 1 });     // 1 мс — хеле кам
  } catch (error) {
    console.log("Ошибка:", error.message);
  }
}

main();

Қадами 5. Кӯтоҳнависиҳои қулай ва api.js-и ниҳоӣ

Боқӣ мемонад даъвати request-ро паси номҳои кӯтоҳ пинҳон кунем. Объекти api бо усулҳои get, post, put, del (калимаи delete дар JS банд аст) — ва код дар лоиҳа мисли ҷумла хонда мешавад. Параметрҳои дархостро бо объект қабул мекунем ва тавассути URLSearchParams ҷамъ мекунем.

api.js · печонандаи тайёр · Ctrl + Enter
const BASE_URL = "https://jsonplaceholder.typicode.com";

async function request(path, { method = "GET", body, timeout = 8000 } = {}) {
  const options = { method, headers: {} };

  if (body !== undefined) {
    options.headers["Content-Type"] = "application/json";
    options.body = JSON.stringify(body);
  }

  const controller = new AbortController();
  options.signal = controller.signal;
  const timer = setTimeout(() => controller.abort(), timeout);

  try {
    const response = await fetch(BASE_URL + path, options);

    if (!response.ok) {
      const error = new Error("HTTP " + response.status);
      error.status = response.status;
      throw error;
    }
    return await response.json();
  } catch (error) {
    if (error.name === "AbortError") {
      throw new Error("сервер не ответил за " + timeout + " мс");
    }
    throw error;
  } finally {
    clearTimeout(timer);
  }
}

const api = {
  get(path, params) {
    const query = params ? "?" + new URLSearchParams(params) : "";
    return request(path + query);
  },
  post: (path, body) => request(path, { method: "POST", body }),
  put: (path, body) => request(path, { method: "PUT", body }),
  del: (path) => request(path, { method: "DELETE" }),
};

async function main() {
  const todos = await api.get("/todos", { userId: 2, _limit: 3 });
  console.log("задач:", todos.length);

  const post = await api.post("/posts", { title: "Салом", userId: 1 });
  console.log("создан пост:", post.id);

  try {
    await api.get("/todos/99999");
  } catch (error) {
    console.log("ошибка:", error.message, error.status);
  }
}

main();
Ин ҳама барои чӣ

Акнун ҳар хато — шабака, 404, 500, таймаут — ба як catch дар намуди хатои оддӣ бо паёми фаҳмо мерасад. Дар дарсҳои оянда мо танҳо api.get(…)-ро даъват мекунем ва натиҷаро мекашем. Файли тайёрро ҳамчун api.js нигоҳ доред: он артефакти дарси шумо мешавад ва дар лоиҳа ба кор меояд.

Муфассалтар хонед: learn.javascript.ru — Fetch: қатъи дархост · MDN — AbortController

Амал: печонандаро анҷом медиҳем

ВАЗИФАИ 6.1

Санҷиши ok-ро илова кун

осон

Дар печонанда санҷиши статус нест: дархости вазифаи вуҷуднадошта «бомуваффақият» объекти холӣ бармегардонад. Санҷишро илова кунед: хатои "HTTP " + status-ро бипартоед ва рамзро дар error.status нигоҳ доред. Коди даъваткунанда аллакай навишта шудааст.

Таҳрир кардан мумкин аст · Ctrl + Enter
const BASE_URL = "https://jsonplaceholder.typicode.com";

async function request(path) {
  const response = await fetch(BASE_URL + path);
  // санҷиши ok — дар ин ҷо
  return response.json();
}

async function main() {
  const todo = await request("/todos/1");
  console.log(todo.title);

  try {
    await request("/todos/99999");
    console.log("ошибки не было");
  } catch (error) {
    console.log(error.message + ", код " + error.status);
  }
}

main();
Натиҷаи интизоршаванда
delectus aut autem
HTTP 404, код 404
Ишора 1

Хато созед, ба он хусусият илова кунед ва бипартоед: const error = new Error(…); error.status = response.status; throw error;

Ишора 2

Ҳамаи инро дар дохили if (!response.ok) { … } — пеш аз return response.json().

ВАЗИФАИ 6.2

get ва post-и кӯтоҳ

миёна

Функсияи request(path, options) аллакай ҳаст. Объекти api-ро бо усулҳои get(path) ва post(path, body) анҷом диҳед, ки request-ро даъват мекунанд. Бадан дар request аллакай худаш ба JSON табдил меёбад.

Таҳрир кардан мумкин аст · Ctrl + Enter
const BASE_URL = "https://jsonplaceholder.typicode.com";

async function request(path, { method = "GET", body } = {}) {
  const options = { method, headers: {} };
  if (body !== undefined) {
    options.headers["Content-Type"] = "application/json";
    options.body = JSON.stringify(body);
  }
  const response = await fetch(BASE_URL + path, options);
  if (!response.ok) {
    throw new Error("HTTP " + response.status);
  }
  return response.json();
}

// const api = { get..., post... };

async function main() {
  const todo = await api.get("/todos/1");
  console.log(todo.title);

  const post = await api.post("/posts", { title: "Салом", userId: 1 });
  console.log("id нового поста:", post.id);
}

main();
Натиҷаи интизоршаванда
delectus aut autem
id нового поста: 101
Ишора 1

get request(path)-ро даъват мекунад, post бошад усул ва баданро мегузаронад: request(path, { method: "POST", body }).

Ишора 2

const api = { get: (path) => request(path), post: (path, body) => request(path, { method: "POST", body }) };

ВАЗИФАИ 6.3

Параметрҳои дархост дар get

миёна

get-ро омӯзонед, ки аргументи дуюмро — объекти параметрҳоро, ки ба сатри дархост табдил меёбад — қабул кунад. Агар параметрҳо набошанд, суроға чун пештара мемонад. Баъд 5 вазифаи корбари дуюмро гиред ва санҷед, ки ҳамаи онҳо аз они ӯянд.

Таҳрир кардан мумкин аст · Ctrl + Enter
const BASE_URL = "https://jsonplaceholder.typicode.com";

async function request(path) {
  const response = await fetch(BASE_URL + path);
  if (!response.ok) {
    throw new Error("HTTP " + response.status);
  }
  return response.json();
}

function get(path, params) {
  // суроғаро бо параметрҳо ҷамъ кунед ва request-ро даъват намоед
}

async function main() {
  const todos = await get("/todos", { userId: 2, _limit: 5 });
  console.log("задач:", todos.length);
  console.log("все от пользователя 2:", todos.every((t) => t.userId === 2));

  const one = await get("/todos/1");
  console.log(one.id);
}

main();
Натиҷаи интизоршаванда
задач: 5
все от пользователя 2: true
1
Ишора 1

Сатри дархост: new URLSearchParams(params).toString(). Вай танҳо дар сурате лозим аст, ки params дода шуда бошад.

Ишора 2

const query = params ? "?" + new URLSearchParams(params) : ""; return request(path + query);

ВАЗИФАИ 6.4

Таймаути дархост

душвор

Ба request таймаутро тавассути AbortController илова кунед: баъд аз гузаштани timeout мс дархост бекор мешавад, ба берун бошад хато бо матни "Таймаут" меравад. Таймерро дар finally бояд тоза кард. Даъват бо timeout: 1 бояд афтад, даъвати оддӣ бошад — кор кунад.

Таҳрир кардан мумкин аст · Ctrl + Enter
const BASE_URL = "https://jsonplaceholder.typicode.com";

async function request(path, { timeout = 8000 } = {}) {
  // AbortController, таймер созед ва signal-ро ба fetch диҳед
  const response = await fetch(BASE_URL + path);
  return response.json();
}

async function main() {
  try {
    await request("/todos/1", { timeout: 1 });
    console.log("успели?!");
  } catch (error) {
    console.log(error.message);
  }

  const todo = await request("/todos/1");
  console.log(todo.title);
}

main();
Натиҷаи интизоршаванда
Таймаут
delectus aut autem
Ишора 1

Лозиманд: const controller = new AbortController();, setTimeout(() => controller.abort(), timeout) ва fetch(url, { signal: controller.signal }).

Ишора 2

Дархостро ба try / catch / finally печонед. Дар catch: агар error.name === "AbortError" бошад — throw new Error("Таймаут"), вагарна хаторо минбаъд гузаронед. Дар finally: clearTimeout(timer).

07 Блоки ЗС: печонандаи fetch аз ЗС ва санҷиши он

Печонандаи fetch-ро ЗС тез ва зебо менависад. Аммо маҳз дар ин ҷо вай «роҳро кӯтоҳ кардан»-ро дӯст медорад: санҷиши response.ok-ро фаромӯш мекунад, ҷавоби бе JSON-ро дастгир намекунад ё фарқ намекунад, ки дар асл чӣ вайрон шуд. Барои ҳамин малакаи имрӯза — на «гирифтани код», балки санҷидани он дар ҷавобҳои бад: 404, 500, на-JSON ва шабакаи гумшуда.

Қоидаҳои курс, ки дар ин ҷо махсусан муҳиманд

1. Аввал 15 дақиқа худатон кӯшиш мекунед: қолабро аз қисми 04 ва қадамҳои печонандаро аз қисми 06 ба ёд оред. 2. Танҳо баъд ба сӯи ЗС мераванд. 3. Ба лоиҳа коде гузоред, ки онро сатр ба сатр шарҳ дода наметавонед — барои печонанда ин маънои онро дорад: шумо медонед, ки ҳар санҷиш барои чӣ аст. 4. На дар «роҳи хушбахтӣ» (200 OK), балки дар ҷавобҳои хатоӣ санҷед: ЗС қариб ҳамеша бо сенарияи хуб мефаромӯшад ва дар бадҳо хато мекунад.

Чӣ тавр пурсидан: бад ва хуб

Формулаи промпти курс: контекст → вазифа → маҳдудиятҳо → формати ҷавоб → санҷиш.

функсия барои fetch нависед
Ман JavaScript меомӯзам, сатҳ — навомӯз, промисҳо, async/await ва try/catch-ро медонам. Печонандаи fetch нависед: URL-и асосӣ, таймаут тавассути AbortController, санҷиши response.ok, хатоҳои фаҳмо. JS-и пок, бе китобхонаҳо, дар як файл, на зиёда аз 40 сатр, бо шарҳҳо ба забони тоҷикӣ барои ҳар блок. Формати ҷавоб: код, баъд рӯйхати «ҳар санҷиш чӣ мекунад» дар 5 банд. Дар охир бигӯед, кадом сенарияҳои хатоиро ман бояд дастӣ санҷам.

Баъд аз ҷавоби ЗС кодро аз рӯи чек-лист гузаронед. Агар ақаллан як банд «не» бошад — шумо хато ёфтед:

Чек-листи санҷиши печонанда

1) Дар ҷавоби 404 хато бо рамзи статус мепарад? 2) Дар ҷавоби 500 — ҳамин тавр? 3) Агар на JSON омад, хато фаҳмост, на «Unexpected token <»? 4) Ҳангоми хомӯш будани шабака (Wi-Fi-ро хомӯш кунед) корбар матни шуморо мебинад, на стеки даҳшатнокро? 5) Таймаут ҳаст ва таймер дар finally тоза мешавад? 6) Бадан ду бор хонда намешавад? 7) Шумо метавонед ҳар сатрро шарҳ диҳед?

Дар сервери воқеӣ санҷидан нобароҳат аст: jsonplaceholder-ро аз рӯи фармоиш «афтондан» мумкин нест. Барои ҳамин касбиён серверро бо пойгоҳи озмоишӣ иваз мекунанд — функсияе, ки ҷавобҳои пешакӣ омодашударо медиҳад. Дар вазифаи поён маҳз чунин пойгоҳ ҳаст ва шумо бояд «печонандаи аз ЗС»-ро санҷед ва ислоҳ кунед.

Амал: хатоҳои ЗС-ро медарёбем

ВАЗИФАИ 7.1

Печонандаи аз ЗС-ро санҷ ва ислоҳ кун

душвор

ЗС функсияи aiRequest-ро дод. Пойгоҳро иҷро кунед — мебинед, ки дар ҷавобҳои бад вай нодуруст рафтор мекунад. Танҳо aiRequest-ро чунон бознависед, ки сенарияҳо аз рӯи ҷадвал рафтор кунанд: ok → маълумот, notfound → хатои HTTP 404, server → HTTP 500, html (статус 200, аммо бадан на JSON) → ответ не JSON, network (дархост нарасид) → сеть недоступна.

Таҳрир кардан мумкин аст · Ctrl + Enter
// --- пойгоҳи озмоишӣ, тағйир надиҳед ---
function fakeFetch(scenario) {
  switch (scenario) {
    case "ok":       return Promise.resolve(new Response(JSON.stringify({ name: "Мадина" })));
    case "notfound": return Promise.resolve(new Response("{}", { status: 404 }));
    case "server":   return Promise.resolve(new Response("Internal Server Error", { status: 500 }));
    case "html":     return Promise.resolve(new Response("<html>Привет</html>"));
    case "network":  return Promise.reject(new TypeError("Failed to fetch"));
  }
}

// --- коди ЗС: ислоҳ кунед ---
async function aiRequest(scenario) {
  const response = await fakeFetch(scenario);
  const data = await response.json();
  return data;
}

// --- санҷиш, тағйир надиҳед ---
async function main() {
  for (const scenario of ["ok", "notfound", "server", "html", "network"]) {
    try {
      const data = await aiRequest(scenario);
      console.log(scenario + ": данные получены: " + data.name);
    } catch (error) {
      console.log(scenario + ": Ошибка: " + error.message);
    }
  }
}

main();
Натиҷаи интизоршаванда
ok: данные получены: Мадина
notfound: Ошибка: HTTP 404
server: Ошибка: HTTP 500
html: Ошибка: ответ не JSON
network: Ошибка: сеть недоступна
Ишора 1

Се ҷо ҳимоя металабанд: худи fakeFetch (шабака), санҷиши response.ok (404 ва 500) ва response.json() (на JSON). Ҳар якро дар try / catch ё if-и худаш.

Ишора 2

Печонед: let response; try { response = await fakeFetch(scenario); } catch { throw new Error("сеть недоступна"); }. Баъд if (!response.ok) throw new Error("HTTP " + response.status);. Баъд try { return await response.json(); } catch { throw new Error("ответ не JSON"); }.

ВАЗИФАИ 7.2

Промпт ва санҷиши худӣ

осон

Промптеро барои ЗС аз рӯи формулаи курс (контекст → вазифа → маҳдудиятҳо → формат → санҷиш) тартиб диҳед: бигзор ЗС печонандаи api.js-ро барои сенарияи шумо нависад — масалан, барои дархостҳо ба dummyjson.com. Онро фиристед, код гиред ва аз рӯи чек-листи ин қисм гузаронед. Дар шарҳ болои код нависед, ки кадоме аз 7 банд нагузашт ва шумо онро чӣ тавр ислоҳ кардед. Санҷиши худкор нест — вазифаро вақте омода шуд, дастӣ қайд кунед.

Таҳрир кардан мумкин аст · Ctrl + Enter
// Промпти ман:
// ...

// Чӣ аз чек-лист нагузашт ва чӣ тавр ислоҳ кардам:
// ...
Ишора 1

Агар ЗС лозимаро надод, ҳамаро аз нав набиворед: ба ӯ нокомии мушаххасро нависед — «дар ҷавоби 404 функсия объекти холӣ баргардонд, на хато партофт».

Ишора 2

Коди ЗС-ро бо коди худии худ аз қисми 06 муқоиса кунед. Чӣ фарқ мекунад? Агар фарқ ба шумо фаҳмо набошад — ин худи боиси пурсидан аст, на нусха бардоштан.

08 Амал дар дарс: дархости аввалин ба API ва чоп дар саҳифа

Акнун ҳамаро якҷоя ҷамъ мекунем: маълумотро аз API-и оммавӣ мегирем, ба консол мебарорем, баъд дар саҳифа мекашем. Қадам ба қадам меравем — баъд аз ҳар қадам код кор мекунад.

Қадами 1. Маълумот дар консол

Ҳамеша аз консол оғоз кунед: аввал боварӣ ҳосил кунед, ки маълумот меояд ва шакли онро мефаҳмед, ва танҳо баъд интерфейсро кашед.

Қадами 1. Аз сервер чӣ меояд · Ctrl + Enter
async function main() {
  const response = await fetch("https://jsonplaceholder.typicode.com/users?_limit=3");
  const users = await response.json();

  console.log("Получили:", users.length);
  users.forEach((user) => {
    console.log(user.name + " — " + user.address.city);
  });
}

main();

Қадами 2. Дар саҳифа мекашем

Маълумот аз fetch — ҳамон массивҳои объектҳост, ки дар дарсҳои 6–8. Пас онҳоро ба унсурҳо бо ҳамон усул табдил медиҳем: createElement ва append. «▶ Иҷро кардан»-ро пахш кунед ва ба рӯйхати тарафи рост нигаред.

Рӯйхати корбарон аз API · Ctrl + Enter
<h3>Участники</h3>
<p id="status">Загрузка...</p>
<ul id="list"></ul>
Пешнамоиш
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.

Ба сохтор диққат диҳед: «Боркунӣ…» → маълумот ё паёми хато. Корбар набояд ба саҳифаи холӣ нигариста, тахмин занад, ки чӣ мегузарад. Дар бораи чунин ҳолатҳо дар дарси 17 муфассал сӯҳбат мекунем.

Амал: дархости худӣ дар саҳифа

ВАЗИФАИ 8.1

Рӯйхати вазифаҳо дар саҳифа

миёна

5 вазифаи аввалро (/todos?_limit=5) бор кунед ва онҳоро ба рӯйхат бароред: пеш аз номи вазифаи иҷрошуда «✔ », пеш аз иҷрошуда нашуда — «○ » меистад. Вақте ҳама кашида шуд, ба консол Показано: 5-ро чоп кунед (шумораи унсурҳои li дар рӯйхат).

Вазифаҳои ман · Ctrl + Enter
<h3>Мои задачи</h3>
<ul id="todos"></ul>
Пешнамоиш
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Натиҷаи интизоршаванда
Показано: 5
Ишора 1

Дархост ва таҷзия ҳамон тавр, ки дар қадами 2. Дар дохили давра нишонро интихоб кунед: const mark = todo.completed ? "✔ " : "○ ";

Ишора 2

li.textContent = mark + todo.title; list.append(li); — console.log-ро бошад баъд аз давра гузоред, вақте унсурҳо аллакай илова шудаанд.

ВАЗИФАИ 8.2

Ду API дар як саҳифа

душвор

Якбора (Promise.all) маълумотро аз ду сервери гуногун бор кунед: корбарон https://jsonplaceholder.typicode.com/users?_limit=3 ва мол https://dummyjson.com/products?limit=3&select=title,price (дар ҷавоб мол дар майдони products ҷойгир аст). Ду рӯйхат чоп кунед: номҳои корбарон ва «ном — нарх $». Ба консол Пользователей: 3, товаров: 3-ро чоп кунед. Агар ягон дархост афтад — хаторо дар блоки #status нишон диҳед.

Корбарон ва мол · Ctrl + Enter
<p id="status">Загрузка...</p>
<h3>Пользователи</h3>
<ul id="users"></ul>
<h3>Товары</h3>
<ul id="products"></ul>
Пешнамоиш
Барои дидани натиҷа «Иҷро кардан»-ро пахш кунед.
Натиҷаи интизоршаванда
Пользователей: 3, товаров: 3
Ишора 1

const [users, productsData] = await Promise.all([load(URL1), load(URL2)]); — ҳарду дархост якбора оғоз мешаванд. Рӯйхати мол: productsData.products.

Ишора 2

Барои ҳар рӯйхат давраи forEach-и худӣ бо createElement("li"). Нарх дар матн: product.title + " — " + product.price + " $".

09 Вазифаи хонагӣ

Маълумотро аз ду API-и гуногун гирифтан ва дар саҳифа кашидан. Артефакт — файли api.js: печонандаи худии шумо болои fetch, ки ҳарду API тавассути он мераванд.

Чӣ кор кардан лозим

  1. Ду API-и оммавиро бе калид ва бо CORS интихоб кунед (дар браузер санҷед, ки ҷавоб меояд): jsonplaceholder.typicode.com, dummyjson.com, api.open-meteo.com (обу ҳаво — координатаҳои Душанберо диҳед: latitude=38.56&longitude=68.77&current=temperature_2m), rickandmortyapi.com. Муҳим: серверҳо бояд гуногун бошанд.
  2. api.js-ро нависед. Функсияи request бо санҷиши response.ok, хато бо status, таймаут ва кӯтоҳнависиҳои get / post. Суроғаи асосиро параметр кунед (як request барои ду сервер).
  3. Маълумоти API-и аввалро бикашед — рӯйхат ё кортҳо (ақалан 5 унсур, ақалан 2 майдон дар ҳар кадом).
  4. Маълумоти API-и дуюмро бикашед — формати дигар (масалан, ҷадвал, як блоки калон ё кортҳо бо расм).
  5. Се ҳолат барои ҳар блок: «Боркунӣ…», маълумот, хатои фаҳмо. Хаторо санҷед: суроғаро ба нодуруст иваз кунед ва боварӣ ҳосил кунед, ки корбар паём мебинад, на холигӣ.
  6. Як амали POST. Ягон шакл ё бо тугма маълумотро ба jsonplaceholder.typicode.com/posts фиристед ва ҷавоби серверро (id-и додашударо) дар саҳифа нишон диҳед.
  7. Санҷиши ЗС. Агар ЗС-ро истифода бурда бошед — промпти худ ва рӯйхати сенарияҳои хатоиро, ки санҷидед (404, шабака, на JSON), замима кунед.

Чӣ супоридан лозим

  • Истинод ба репозиторий дар GitHub: index.html, api.js, app.js, style.css.
  • Ду скриншот: саҳифа бо маълумот ва саҳифа бо ҳолати хато.
  • README-и кӯтоҳ: кадом ду API-ро интихоб кардед ва онҳо чӣ тавр фарқ мекунанд.

Чӣ тавр баҳо медиҳем (0–10)

ЧӣХолҳо
api.js: санҷиши ok, хатоҳои фаҳмо, get / post3
Маълумоти ду API-и гуногун ба саҳифа бароварда шудааст2
Ҳолатҳои «Боркунӣ…» ва «Хато» дар ҳарду блок кор мекунанд2
Дархости POST бо нишон додани ҷавоби сервер1
Таймаут ва тоза кардани таймер дар finally1
Коди тоза: дархост такрор намешавад, номҳо фаҳмо, коди ЗС-ро шумо шарҳ дода метавонед1
Пеш аз супоридан

Интернетро хомӯш кунед (ё дар DevTools дар ҷадвали Network ҳолати Offline-ро гузоред) ва саҳифаро аз нав бор кунед. Агар ба ҷои хатои фаҳмо экрани холӣ ё сурхиро дар консол бинед — коркарди хатоҳоро такмил диҳед.

✓ Лавҳаи ёддошти дарс

  • HTTP: клиент дархост мефиристад (усул + URL + сарлавҳаҳо + бадан), сервер ҷавоб медиҳад (статус + сарлавҳаҳо + бадан). Маълумот аксаран дар формати JSON.
  • Усулҳо: GET — гирифтан, POST — сохтан, PUT — иваз кардан, PATCH — як қисмро тағйир додан, DELETE — нест кардан.
  • Статусҳо: 2xx муваффақият (200, 201), 3xx равонакунӣ, 4xx хатои клиент (404, 401, 403), 5xx хатои сервер (500).
  • fetch промис бо response (статус ва сарлавҳаҳо) бармегардонад. Баданро ҷудо ва як маротиба мехонем: await response.json() ё text().
  • 404 ва 500 — хатои fetch нестанд. response.ok-ро санҷед ва хаторо худатон бипартоед. Хатои шабакавӣ (шабака нест, сервери нодуруст) — промиси радшуда, TypeError.
  • Қолаб: try { const r = await fetch(url); if (!r.ok) throw new Error("HTTP " + r.status); const data = await r.json(); … } catch (e) { … } finally { … }
  • POST: fetch(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(data) }). Бадан — ҳамеша сатр.
  • URL ва параметрҳо: new URL(…) суроғаро таҷзия мекунад, new URLSearchParams(объект) сатри дархостро ҷамъ мекунад.
  • api.js: як функсияи request — суроғаи асосӣ, сарлавҳаҳо, JSON, санҷиши ok, таймаут тавассути AbortController; дар боло — get / post.
  • Бо ЗС: аввал худатон, баъд промпт аз рӯи формула. Печонандаи аз ЗС-ро дар ҷавобҳои бад месанҷем: 404, 500, на-JSON, шабака нест, таймаут.