IlmHamroh
JavaScript Full-stack/25-qism. HTTP, Express va REST API10/51-dars16 daqiqa
Mundarija (29)

Express req obyekti: req.params, req.query, req.body, req.get, req.ip va req.is

Qisqacha: req — kiruvchi so'rov haqidagi hamma narsa. Express uni node:http ning IncomingMessage iga qo'shimcha xususiyatlar bilan beradi: req.params (yo'ldagi :id), req.query (? dan keyingi qism), req.body (tana — faqat express.json() kabi middleware bilan), req.get() (sarlavha), req.ip, req.hostname, req.is(). Uchta tuzoq bor. req.params.id doim satr. Express 5 da req.query ni o'zgartirib bo'lmaydi (faqat getter). Content-Type JSON bo'lmasa, req.body jim undefined bo'ladi — xato yo'q. Biz shu tuzoqlarni testlar bilan topdik.

Bu darsda

  • req.params, req.query, req.body qayerdan kelishini va qanday turda ekanini bilasiz.
  • Express 5 ning "simple" query parser'ini va uning extended dan farqini ko'rasiz.
  • express.json() ning jim undefined tuzog'ini tushunib, 415 ni o'zingiz qaytarasiz.
  • req.get(), req.is(), req.ip, req.hostname, req.path, req.originalUrl ni ishlatasiz.
  • fetch shartli so'rovga o'zi no-cache qo'shishini ko'rasiz.

Oldin bilishingiz kerak: Express'ga kirish va Express 5, Qo'lda routing va query parametrlar, Request body o'qish, Reverse proxy orqasida Node.

1. Nega bu kerak?

Qo'lda routing darsida so'rovdan ma'lumotni o'zimiz qazib olardik: new URL(req.url, …), searchParams.get(...), regex'dan m[1], tanani bo'laklab yig'ish. Express buni req ga tayyor xususiyatlar sifatida qo'yadi. Qulay — lekin har xususiyatning o'z qoidasi bor. Ularni bilmasangiz, xatolar jim o'tib ketadi: id bo'yicha qidiruv hech narsa topmaydi, filtr ishlamaydi, tana yo'qoladi.

O'xshatish: pochta posilkasi. Manzil (req.path va req.params), qo'shimcha yorliqlar (req.query), yuboruvchi haqidagi qog'ozlar (sarlavhalar, req.get()), qutining ichi (req.body) va "kimdan" muhri (req.ip). Qutini ochish uchun pichoq kerak — bu express.json(). Pichoqsiz quti yopiq qoladi, lekin hech kim "ochilmadi" deb aytmaydi.

flowchart LR
  U["PATCH /vazifalar/42?tez=1"] --> P["req.params<br/>{ id: '42' }"]
  U --> Q["req.query<br/>{ tez: '1' }"]
  S["Sarlavhalar"] --> G["req.get()<br/>req.is()"]
  B["Tana (stream)"] --> J["express.json()"]
  J --> RB["req.body"]
  K["Soket / X-Forwarded-For"] --> IP["req.ip"]

O'ngdagi har quti — req dagi xususiyat. req.body ga faqat middleware orqali yetib boriladi.

2. req.params — yo'ldagi qismlar

2.1 Doim satr

Marshrut /vazifalar/:id — :id yo'l parametri (route parameter): URL'ning shu qismi req.params.id ga tushadi. Biz ishga tushirdik (Express 5.3.0). Chiqishda "turi" maydoniga qarang:

text
GET /vazifalar/42?sort=-yaratildi&teg=uy
{"params":{"id":"42"},"turi":"string","query":{"sort":"-yaratildi","teg":"uy"},"get":"application/json"}

Nima bo'ldi? "42" — qo'shtirnoqda, turi string. URL — matn, Express uni songa aylantirmaydi. Ombordagi Map ning kalitlari esa son (42). Map.get("42") satr kalitni qidiradi va hech narsa topmaydi — jim 404. Shuning uchun aylantirish va tekshirish o'zimizda.

2.2 idniOl — tekshirib aylantirish

vazifalar-api dagi yordamchi (kanon):

js
function idniOl(xom) {
  if (!/^[1-9]\d{0,9}$/.test(xom)) {
    throw new Error("id — musbat butun son");
  }
  return Number(xom);
}

for (const x of ["42", "abc", "0", "007", "1e3", "-5"]) {
  try {
    console.log(x, "→", idniOl(x));
  } catch (e) {
    console.log(x, "→", e.message);
  }
}

Konsolda:

text
42 → 42
abc → id — musbat butun son
0 → id — musbat butun son
007 → id — musbat butun son
1e3 → id — musbat butun son
-5 → id — musbat butun son

Nega Number(xom) ning o'zi yetmaydi? Number("1e3") — 1000, Number("") — 0, Number(" 7 ") — 7. Bularning hammasi "son" bo'lib o'tib ketadi. Regex aniq aytadi: birinchi raqam 1–9, jami 10 raqamgacha. Kanonda bu xato HttpXato(400, …) — mijozga 400 Bad Request. Jonli tekshiruv (kanon, holat 13):

bash
curl -i -X PATCH $A/vazifalar/abc \
  -H 'Content-Type: application/json' -d '{}'
text
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Content-Length: 34
…
{"xato":"id — musbat butun son"}

Maslahat: Bir nechta parametr ham bo'ladi: /foydalanuvchilar/:fid/vazifalar/:vid → req.params.fid, req.params.vid. Express 5 dagi yangi yo'l sintaksisi ({/:ixtiyoriy}, *splat) — Express 5 darsida.

3. req.query — so'rov satri

3.1 Express 5 ning "simple" parser'i

? dan keyingi qism req.query obyektiga aylanadi. Parser (tahlilchi) — satrni obyektga aylantiradigan funksiya. Express 5 da sukut parser — "simple" (Node'ning querystring moduli). Kanon tajribasi — har qatorda chapda so'rov, o'ngda req.query; qiymatlarning turiga va qavslarga qarang:

text
GET /q?teg=uy&teg=ish&sahifa=2 → {"teg":["uy","ish"],"sahifa":"2"}
GET /q?filtr[bajarildi]=true → {"filtr[bajarildi]":"true"}
GET /q?a=1&a=2&a=3 → {"a":["1","2","3"]}
GET /q?bo%27sh=&x → {"bo'sh":"","x":""}
'extended' (qs) bilan: /q?filtr[bajarildi]=true → {"filtr":{"bajarildi":"true"}}

To'rt qoida:

  1. Hamma qiymat satr: sahifa — "2", son emas.
  2. Takrorlangan kalit — massiv: teg=uy&teg=ish → ["uy", "ish"]. Bitta bo'lsa — satr. Demak req.query.teg ning turi string | string[] | undefined — ikkalasini ham kutish kerak.
  3. Qavslar oddiy belgi: filtr[bajarildi] — kalit nomi, ichma-ich obyekt emas.
  4. extended (app.set("query parser", "extended")) — qs kutubxonasi qavslarni obyektga aylantiradi. Express 4 da sukut shu edi. 5 da o'chirildi: ichma-ich obyektlar va ulkan massivlar hujum uchun qulay edi.

Bu mantiqni brauzerda ham ko'rish mumkin — URLSearchParams dan Express'ga o'xshash obyekt yasaymiz:

js
function oddiyQuery(qs) {
  const natija = {};
  for (const [k, v] of new URLSearchParams(qs)) {
    if (!(k in natija)) natija[k] = v;
    else if (Array.isArray(natija[k])) natija[k].push(v);
    else natija[k] = [natija[k], v];
  }
  return natija;
}

console.log(oddiyQuery("teg=uy&teg=ish&sahifa=2"));
console.log(oddiyQuery("filtr[bajarildi]=true"));

Konsolda:

text
{ teg: [ 'uy', 'ish' ], sahifa: '2' }
{ 'filtr[bajarildi]': 'true' }

Natija kanondagi Express chiqishi bilan bir xil.

3.2 req.query — faqat o'qish

Express 5 da req.query — getter (har o'qishda hisoblanadigan xususiyat, getter va setter darsi). Unga yangi qiymat yozib bo'lmaydi. Kanon:

text
TypeError: Cannot set property query of #<IncomingMessage> which has only a getter

"IncomingMessage ning query xususiyatiga yozib bo'lmaydi — unda faqat getter bor". Express 4 da ko'p middleware'lar tozalangan query'ni req.query = … bilan qayta yozardi. 5 da bunday kod shu xato bilan yiqiladi. Tekshirilgan qiymatni alohida o'zgaruvchiga yoki res.locals ga (res darsi) saqlang.

3.3 vazifalar-api da

Hozircha bitta filtr — ?bajarildi=true|false. Express'ga kirish darsida ko'chirgan ilova.ts dagi qism:

ts
.get((req, res) => {
  const b = req.query.bajarildi;
  if (b !== undefined && b !== "true" && b !== "false") {
    throw new HttpXato(400, "bajarildi — true yoki false");
  }
  const royxat = ombor.royxat();
  res.json(b === undefined
    ? royxat
    : royxat.filter((v) => v.bajarildi === (b === "true")));
})

?bajarildi=ha → 400, ?bajarildi=true&bajarildi=false (massiv) ham 400 — massiv "true" ga teng emas. Filtrlash darsida bu tekshiruv kengayadi: noma'lum parametr ham 400.

Tekshirib ko'ring: GET /vazifalar?limit=10. req.query.limit + 5 nima beradi?

Javob

"105" — satr birlashtirildi, chunki limit — "10" satri. Avval tekshirib songa aylantiring (idniOl ga o'xshash). Bu tuzoq req.params dagi bilan bir xil: URL'dan kelgan hamma narsa — matn.

4. req.body va express.json()

4.1 Tana middleware'siz yo'q

Tana o'qish darsida ko'rganingizdek, tana — stream. Express uni o'zi o'qimaydi. express.json() middleware'i o'qiydi, JSON'ni tahlil qiladi va natijani req.body ga yozadi:

js
app.use(express.json({ limit: "16kb" }));

limit — 413 darsidagi hajm chegarasi. Sukut 100 KB. Buzuq JSON → 400, katta tana → 413. Ikkalasini ham Express xato sifatida keyingi bosqichga uzatadi — ularni qanday chiroyli JSON javobga aylantirish middleware darsida.

4.2 Jim undefined — testlar topgan tuzoq

Content-Type application/json bo'lmasa nima bo'ladi? Kanon tajribasi — har qatorda req.is() ning ikki javobi va body. Oxirgi ustunga qarang:

text
Content-Type: application/json → {"req.is(json)":"application/json","req.is(['json','text'])":"json","body":"undefined"}
Content-Type: application/json; charset=utf-8 → {"req.is(json)":"application/json","req.is(['json','text'])":"json","body":"undefined"}
Content-Type: text/plain → {"req.is(json)":false,"req.is(['json','text'])":"text","body":"undefined"}
tanasiz POST → {"req.is(json)":false,"req.is(['json','text'])":false,"body":"undefined"}

Nima bo'ldi? Bu tajribada express.json() umuman ulanmagan — shuning uchun hamma qatorda undefined. req.is() esa tanani o'qimasdan, faqat sarlavhaga qarab javob berdi. vazifalar-api da express.json() ulangan. Testlar topgan holat: Content-Type: text/plain bilan {"matn":"…"} yuborilsa, express.json() tanani o'qimaydi (turi mos emas), xato ham bermaydi. req.body — undefined (Express 4 da shu holatda bo'sh obyekt {} edi — rasmiy ko'chish qo'llanmasiga ko'ra). Keyingi tekshiruv "matn yo'q" deb 422 qaytaradi. Mijoz "Content-Type noto'g'ri" o'rniga "matn kerak" xabarini oladi va nimani tuzatishni bilmaydi.

To'g'ri javob — 415 Unsupported Media Type ("qo'llanmaydigan media turi"). Uni o'zimiz qaytaramiz — req.is() bilan.

4.3 req.is()

req.is(tur) so'rovning Content-Type ini tekshiradi va uch xil qiymat qaytaradi (yuqoridagi chiqishdan):

Holat req.is("application/json")
application/json yoki …; charset=utf-8 "application/json" — mos tur
boshqa tur (text/plain) false
tana yo'q null (hujjatga ko'ra)

Massiv berilsa (["json", "text"]), birinchi mos qisqa nomni qaytaradi. Bu mantiqning soddalashtirilgan modeli — parametrlarni (; charset=…) tashlab, asosiy turni solishtirish:

js
function turMi(contentType, kerak) {
  if (!contentType) return null; // tana yo'q
  const asosiy = contentType.split(";")[0].trim().toLowerCase();
  return asosiy === kerak ? kerak : false;
}

console.log(turMi("application/json", "application/json"));
console.log(turMi("Application/JSON; charset=utf-8",
  "application/json"));
console.log(turMi("text/plain", "application/json"));
console.log(turMi(undefined, "application/json"));

Konsolda:

text
application/json
application/json
false
null

Haqiqiy req.is ko'proq narsani biladi (*/*, +json qo'shimchasi), lekin g'oya shu.

Kanondagi middleware — src/umumiy/json-kerak.ts:

ts
// Express 5: Content-Type JSON bo'lmasa express.json() tanani
// o'qimaydi va req.body = undefined — xato YO'Q. Turini o'zimiz
export const jsonKerak: RequestHandler = (req, _res, next) => {
  if (req.is("application/json") !== "application/json")
    throw new HttpXato(415,
      "Content-Type: application/json bo'lishi kerak");
  next();
};

U faqat POST va PATCH marshrutlariga qo'yiladi — tanasi bo'lishi kerak bo'lganlarga. Kanon birinchi variantda uni global qilgan edi va yangi xato chiqdi: tanasiz PUT /vazifalar ham 415 oldi, 405 o'rniga. fetch tanasiz POST va PUT ga ham Content-Length: 0 yuboradi. Shunda req.is() false qaytaradi, null emas. Saboq: tekshiruvni kerakli joyga qo'ying. Middleware'ni marshrutga ulash — middleware darsida.

5. Sarlavhalar, IP va manzil qismlari

5.1 req.get() va req.headers

req.headers — node:http dan, kalitlar kichik harfda. req.get(nom) — katta-kichik harfga qaramaydi: req.get("ACCEPT") ham, req.get("accept") ham bir xil (biz sinadik — yuqoridagi "get":"application/json"). Referer/Referrer ikkalasini ham tushunadi. Sarlavha yo'q bo'lsa — undefined.

5.2 Manzil xususiyatlari

Kanon tajribasi GET /q?x=1 uchun. Chiqish bitta uzun JSON qator — uni pastdagi jadvalda bo'lib o'qiymiz:

text
{"query":{"x":"1"},"req.query = ... ":"TypeError: Cannot set property query of #<IncomingMessage> which has only a getter","ip":"127.0.0.1","hostname":"127.0.0.1","req.get('user-agent')":"node","protocol":"http","path":"/q","originalUrl":"/q?x=1"}
Xususiyat Qiymat Izoh
req.path /q query'siz yo'l
req.originalUrl /q?x=1 to'liq, o'zgarmagan
req.url router ichida qisqaradi node:http dan
req.baseUrl router ulangan yo'l Router darsida
req.protocol http trust proxy bilan X-Forwarded-Proto
req.hostname 127.0.0.1 Host sarlavhasidan, portsiz
req.ip 127.0.0.1 trust proxy ga bog'liq

req.ip, req.ips, req.protocol va req.hostname — reverse proxy darsida to'liq o'lchangan. trust proxy noto'g'ri bo'lsa, ular yo noto'g'ri, yo soxtalashtirilgan bo'ladi. user-agent — node: fetch o'zini shunday tanishtiradi (fetch darsi).

5.3 req.cookies

req.cookies Express'ning o'zida yo'q — cookie-parser middleware'i qo'shadi. Usiz cookie'lar faqat req.get("cookie") da xom satr. vazifalar-api da cookie yo'q; ular cookie chuqur darsida (28-qism) kerak bo'ladi.

6. fetch va shartli so'rov: kutilmagan 200

Express ko'chishidan keyin bitta test yiqildi: static fayl uchun ETag bilan fetch 304 o'rniga 200 oldi. Shartli so'rov — "fayl o'zgargan bo'lsagina yubor" degan so'rov: mijoz eski ETag'ni If-None-Match sarlavhasida yuboradi, o'zgarmagan bo'lsa server tanasiz 304 qaytaradi. Static fayl darsida o'z serverimiz 304 bergan edi. Nega Express bermadi? Biz ishga tushirdik — server kelgan Cache-Control sarlavhasini chiqaradi, bir xil ETag'ni fetch va node:http bilan yuboramiz. Ikkinchi qatorga qarang:

text
cache-control: -
cache-control: no-cache
fetch: 200
cache-control: -
node:http: 304

Nima bo'ldi? Birinchi qator — ETag olish uchun oddiy so'rov. Ikkinchisi — fetch + If-None-Match: so'rovda biz yozmagan Cache-Control: no-cache paydo bo'ldi. undici (Node'dagi fetch ning ichki kutubxonasi) Fetch standartiga amal qiladi: shartli sarlavhani qo'lda qo'shgan so'rovga keshni chetlab o'tish sarlavhalarini (Cache-Control: no-cache, Pragma: no-cache) o'zi qo'shadi. Express'ning fresh tekshiruvi esa no-cache ni hurmat qiladi — "mijoz yangi javob so'rayapti" — va 200 beradi. node:http bunday sarlavha qo'shmaydi — 304.

Bizning eski statik.ts Cache-Control ga qaramagan edi — shuning uchun u 304 bergan. Kanon testlari shartli so'rovlarni endi node:http bilan yuboradi (test/yordamchi.ts → xomSorov). Fetch standartiga ko'ra brauzerdagi fetch ham shunday qilishi kerak (sukut kesh rejimi shartli sarlavhali so'rovda "no-store" ga o'tadi) — lekin brauzerda biz buni sinamadik. Bu topilma HTTP kesh darsida yana kerak bo'ladi.

7. Hujumchi nigohi

req dagi hamma narsa — mijozdan. Ishonchli faqat req.socket.remoteAddress (va to'g'ri sozlangan req.ip).

Kirish Hujum Himoya
req.params.id 1e3, -1, ../ regex bilan oq ro'yxat (idniOl)
req.query massiv yuborish (?a=1&a=2) turini tekshirish
req.query (extended) ?a[__proto__][x]=1, ulkan ichma-ich obyekt "simple" parser (Express 5 sukuti)
req.body 100 MB tana, buzuq JSON limit, 413/400
req.body kutilmagan maydon ({"admin": true}) oq ro'yxat validatsiyasi (validatsiya darsi)
req.hostname, req.ip soxta X-Forwarded-* to'g'ri trust proxy

Ikkinchi qator haqida: ?bajarildi=true&bajarildi=false — massiv. Kod req.query.bajarildi === "true" deb tekshirsa — false, .toLowerCase() chaqirsa — TypeError va 500. Turini doim tekshiring.

8. API qadami: req bilan marshrutlar (holat 13, 2-qism)

Holat 13 ning ikkinchi bo'lagi. Hali commit qilmang. Kod o'tgan darsda to'liq ko'chirilgan — bugun ilova.ts dagi req bilan ishlaydigan qismlarni o'qidik:

  • idniOl(req.params.id) — regex ^[1-9]\d{0,9}$, xato bo'lsa 400. Avval regex /^\/vazifalar\/(\d+)$/ faqat raqamli yo'llarni ushlardi va /vazifalar/abc 404 olardi. Endi /:id istalgan satrni ushlaydi — shuning uchun tekshiruv kerak.
  • req.query.bajarildi — «vazifalar-api da» bo'limidagi kod.
  • src/umumiy/json-kerak.ts — jsonKerak middleware'i (415).
  • req.body — express.json({ limit: "16kb" }) dan.

Bugungi yagona o'zgarish — test. test/api.test.ts dagi "xatolar" testining oxiriga (kanon qatori):

ts
assert.equal((await fetch(`${asos}/vazifalar/abc`)).status, 400);

Testlar soni 7 bo'lib qoladi — qator mavjud testga qo'shildi. npm run check — yashil (biz tekshirdik).

9. Ko'p uchraydigan xatolar

Belgi Sabab Davosi
id bo'yicha hech narsa topilmaydi req.params.id — satr tekshirib Number
req.body — undefined express.json() yo'q yoki Content-Type JSON emas middleware + 415
TypeError: Cannot set property query … Express 5 da req.query getter boshqa o'zgaruvchiga saqlash
req.query.teg.toLowerCase is not a function takrorlangan kalit — massiv Array.isArray tekshiruvi
?filtr[x]=1 obyekt bo'lmadi "simple" parser qavssiz nomlar yoki extended (ehtiyot bilan)
fetch + ETag → 200 undici no-cache qo'shadi testda node:http

req.query.teg.toLowerCase is not a function — "toLowerCase funksiya emas": massivda bunday metod yo'q.

10. Mashqlar

Yechimlar kurs/mashqlar/25/10-req/ da.

1-mashq (oson): to'ldiring

  • /vazifalar/:id dagi id turi —
  • Express 5 ning sukut query parser'i —
  • JSON tanani req.body ga o'qiydigan middleware — express.()
  • Content-Type mos kelmasa qaytariladigan status —
  • Query'siz yo'l — req.
Yechim
  • string — URL matn; o'zingiz aylantirasiz.
  • simple — takroriy kalit massiv, qavslar oddiy belgi.
  • json — limit bilan.
  • 415 Unsupported Media Type.
  • path — originalUrl esa query bilan.

2-mashq (o'rta): birQiymat

Query parametrini xavfsiz o'qiydigan birQiymat(query, nom) funksiyasini yozing: yo'q bo'lsa undefined; massiv bo'lsa Error("<nom> bir marta berilsin"); satr bo'lsa — o'zini qaytarsin. oddiyQuery («Express 5 ning "simple" parser'i» bo'limidan) bilan sinang. Eslatma: Array.isArray — massivlar.

Yechim
js
function oddiyQuery(qs) {
  const natija = {};
  for (const [k, v] of new URLSearchParams(qs)) {
    if (!(k in natija)) natija[k] = v;
    else if (Array.isArray(natija[k])) natija[k].push(v);
    else natija[k] = [natija[k], v];
  }
  return natija;
}

function birQiymat(query, nom) {
  const q = query[nom];
  if (Array.isArray(q)) throw new Error(`${nom} bir marta berilsin`);
  return q;
}

for (const qs of ["q=osh", "", "q=osh&q=manti"]) {
  try {
    const q = birQiymat(oddiyQuery(qs), "q");
    console.log(JSON.stringify(qs), "→", q);
  } catch (e) {
    console.log(JSON.stringify(qs), "→", e.message);
  }
}

Konsolda:

text
"q=osh" → osh
"" → undefined
"q=osh&q=manti" → q bir marta berilsin

Kanon filtrlash darsida xuddi shu qoidani qo'llaydi: q=a&q=b → 400 ("bir marta").

3-mashq (qiyin): jsonKerak Express'da

Express 5.3.0 bilan POST /taomlar yozing: jsonKerak middleware'i (req.is bilan) 415 qaytarsin, express.json() tanani o'qisin, javob — req.body. Uch so'rov yuboring: JSON, text/plain va tanasiz POST. Har birining status va javobini chiqaring. Eslatma: middleware marshrutga ikkinchi argument sifatida beriladi — app.post("/taomlar", jsonKerak, ishlovchi); next() — keyingisiga o'tish (middleware darsida chuqur).

Yechim
js
import express from "express";

const app = express();
app.use(express.json());

function jsonKerak(req, res, next) {
  if (req.is("application/json") !== "application/json") {
    return res.status(415).json({ xato: "faqat application/json" });
  }
  next();
}
app.post("/taomlar", jsonKerak, (req, res) => {
  res.status(201).json(req.body);
});

const server = app.listen(0, "127.0.0.1");
await new Promise((ok) => server.once("listening", ok));
const url = `http://127.0.0.1:${server.address().port}/taomlar`;

const sorovlar = [
  { "Content-Type": "application/json" },
  { "Content-Type": "text/plain" },
  null,
];
for (const headers of sorovlar) {
  const opts = headers
    ? { method: "POST", headers, body: '{"nom":"osh"}' }
    : { method: "POST" };
  const r = await fetch(url, opts);
  console.log(r.status, await r.text());
}
server.closeAllConnections();
server.close();

Konsolda:

text
201 {"nom":"osh"}
415 {"xato":"faqat application/json"}
415 {"xato":"faqat application/json"}

Tanasiz POST ham 415 oldi: fetch Content-Length: 0 yubordi va req.is false qaytardi. Tanasiz so'rov uchun boshqa javob kerak bo'lsa (masalan 400 "tana kerak") — req.is(...) === null ni ham tekshiring, lekin fetch bilan bu holat deyarli kelmaydi.

4-mashq: API qadami

Testga GET /vazifalar/abc → 400 qatorini qo'shing. Keyin tajriba: ilova.ts da idniOl ni vaqtincha Number(req.params.id) ga almashtiring va npm test qiling. Qaysi tekshiruv yiqiladi va /vazifalar/abc endi nima qaytaradi? Asl holiga qaytaring. Commit qilmang.

Yechim

Qator — «API qadami» bo'limida. Number("abc") — NaN, ombor.ol(NaN) hech narsa topmaydi, natija 404 "Vazifa NaN topilmadi" — 400 kutilgan edi, test yiqiladi. Xabardagi NaN ham mijozga keraksiz ichki tafsilot. 3-mashqdagi jsonKerak kanonda throw new HttpXato(415, …) bilan — xato ishlovchi uni JSON'ga aylantiradi (middleware darsi).

11. Real ishda

  • Har Express loyihasida — params, query, body ni tekshirish birinchi qatlam; odatda Zod yoki shunga o'xshash sxema bilan (Zod darsi).
  • Express 4 → 5 ko'chishida — req.query = … yozadigan eski middleware'lar yiqiladi; qs parser'iga tayangan frontend so'rovlari (filtr[x]=1) buziladi.
  • Webhook'lar (Click, Payme, Telegram) — imzoni tekshirish uchun xom tana kerak: express.raw() (mashhur middleware'lar).
  • Intervyu: "req.params va req.query farqi?", "req.body nega undefined?", "req.ip qachon noto'g'ri?".

Xulosa

  • req.params va req.query — doim satr (query'da massiv ham); aylantirish va tekshirish — sizda.
  • Express 5: "simple" query parser (qavslar — oddiy belgi), req.query faqat o'qiladi.
  • req.body faqat express.json() bilan; Content-Type JSON bo'lmasa jim undefined — req.is() bilan 415 qaytaring, faqat tanali marshrutlarda.
  • req.get() harfga qaramaydi; req.ip, req.protocol, req.hostname — trust proxy ga bog'liq; req.cookies — cookie-parser bilan.
  • fetch + If-None-Match → undici no-cache qo'shadi → Express 200 beradi; shartli so'rovni node:http bilan sinang.

Keyingi dars: res obyekti — res.status, json, send, sendStatus, redirect, set, res.locals va headersSent.

Manbalar

  • Express 5.x API hujjati — req.params, req.query, req.is(), req.get(), req.ip, "query parser" sozlamasi: https://expressjs.com/en/5x/api.html#req
  • Fetch Standard — HTTP-network-or-cache fetch, shartli sarlavhalar va no-cache: https://fetch.spec.whatwg.org/
  • Kanon: req/res tajribasi (Express 5.3.0, Node 24.21.0), holat 13 (json-kerak.ts, marshrut.ts, jonli curl), topilmalar: jim req.body undefined, global jsonKerak → 405 o'rniga 415, fetch + If-None-Match. params va fetch/node:http 304 solishtiruvi — biz ishga tushirdik.
Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
Express req obyekti: req.params, req.query, req.body, req.get, req.ip va req.is — IlmHamroh