Mundarija (29)
- Bu darsda
- 1. Nega bu kerak?
- 2. req.params — yo'ldagi qismlar
- 2.1 Doim satr
- 2.2 idniOl — tekshirib aylantirish
- 3. req.query — so'rov satri
- 3.1 Express 5 ning "simple" parser'i
- 3.2 req.query — faqat o'qish
- 3.3 vazifalar-api da
- 4. req.body va express.json()
- 4.1 Tana middleware'siz yo'q
- 4.2 Jim undefined — testlar topgan tuzoq
- 4.3 req.is()
- 5. Sarlavhalar, IP va manzil qismlari
- 5.1 req.get() va req.headers
- 5.2 Manzil xususiyatlari
- 5.3 req.cookies
- 6. fetch va shartli so'rov: kutilmagan 200
- 7. Hujumchi nigohi
- 8. API qadami: req bilan marshrutlar (holat 13, 2-qism)
- 9. Ko'p uchraydigan xatolar
- 10. Mashqlar
- 1-mashq (oson): to'ldiring
- 2-mashq (o'rta): birQiymat
- 3-mashq (qiyin): jsonKerak Express'da
- 4-mashq: API qadami
- 11. Real ishda
- Xulosa
- Manbalar
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 uninode:httpningIncomingMessageiga qo'shimcha xususiyatlar bilan beradi:req.params(yo'ldagi:id),req.query(?dan keyingi qism),req.body(tana — faqatexpress.json()kabi middleware bilan),req.get()(sarlavha),req.ip,req.hostname,req.is(). Uchta tuzoq bor.req.params.iddoim satr. Express 5 dareq.queryni o'zgartirib bo'lmaydi (faqat getter). Content-Type JSON bo'lmasa,req.bodyjimundefinedbo'ladi — xato yo'q. Biz shu tuzoqlarni testlar bilan topdik.
Bu darsda
req.params,req.query,req.bodyqayerdan kelishini va qanday turda ekanini bilasiz.- Express 5 ning "simple" query parser'ini va uning
extendeddan farqini ko'rasiz. express.json()ning jimundefinedtuzog'ini tushunib, 415 ni o'zingiz qaytarasiz.req.get(),req.is(),req.ip,req.hostname,req.path,req.originalUrlni ishlatasiz.fetchshartli so'rovga o'zino-cacheqo'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:
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):
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:
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 sonNega 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):
curl -i -X PATCH $A/vazifalar/abc \
-H 'Content-Type: application/json' -d '{}'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:
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:
- Hamma qiymat satr:
sahifa—"2", son emas. - Takrorlangan kalit — massiv:
teg=uy&teg=ish→["uy", "ish"]. Bitta bo'lsa — satr. Demakreq.query.tegning turistring | string[] | undefined— ikkalasini ham kutish kerak. - Qavslar oddiy belgi:
filtr[bajarildi]— kalit nomi, ichma-ich obyekt emas. extended(app.set("query parser", "extended")) —qskutubxonasi 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:
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:
{ 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:
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:
.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 + 5nima 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:
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:
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:
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:
application/json
application/json
false
nullHaqiqiy req.is ko'proq narsani biladi (*/*, +json qo'shimchasi), lekin g'oya shu.
Kanondagi middleware — src/umumiy/json-kerak.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:
{"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:
cache-control: -
cache-control: no-cache
fetch: 200
cache-control: -
node:http: 304Nima 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/abc404 olardi. Endi/:idistalgan satrni ushlaydi — shuning uchun tekshiruv kerak.req.query.bajarildi— «vazifalar-apida» bo'limidagi kod.src/umumiy/json-kerak.ts—jsonKerakmiddleware'i (415).req.body—express.json({ limit: "16kb" })dan.
Bugungi yagona o'zgarish — test. test/api.test.ts dagi "xatolar" testining oxiriga (kanon qatori):
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/:iddagiidturi —- Express 5 ning sukut query parser'i —
- JSON tanani
req.bodyga 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 —
limitbilan. - 415 Unsupported Media Type.
- path —
originalUrlesa 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
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:
"q=osh" → osh
"" → undefined
"q=osh&q=manti" → q bir marta berilsinKanon 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
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:
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,bodyni 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;qsparser'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.paramsvareq.queryfarqi?", "req.bodynegaundefined?", "req.ipqachon noto'g'ri?".
Xulosa
req.paramsvareq.query— doim satr (query'da massiv ham); aylantirish va tekshirish — sizda.- Express 5: "simple" query parser (qavslar — oddiy belgi),
req.queryfaqat o'qiladi. req.bodyfaqatexpress.json()bilan; Content-Type JSON bo'lmasa jimundefined—req.is()bilan 415 qaytaring, faqat tanali marshrutlarda.req.get()harfga qaramaydi;req.ip,req.protocol,req.hostname—trust proxyga bog'liq;req.cookies—cookie-parserbilan.fetch+If-None-Match→ undicino-cacheqo'shadi → Express 200 beradi; shartli so'rovninode:httpbilan 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: jimreq.body undefined, globaljsonKerak→ 405 o'rniga 415,fetch+If-None-Match.paramsvafetch/node:http304 solishtiruvi — biz ishga tushirdik.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!