Express forma va validatsiya
CRUD API darsida title bo’shligini tekshirdik —
bitta if bilan. Haqiqiy formada maydon beshta bo’ladi: biri majburiy,
biri son, biri email, biri uzunlik chegarasiga ega. Bitta if yetmaydi.
Bu darsda formadan kelgan ma’lumotni qabul qilishni va uni tartibli
tekshirishni ko’ramiz.
HTML forma ma’lumotni boshqacha yuboradi
public/form.html faylini yarating:
<!DOCTYPE html>
<html lang="uz">
<head>
<meta charset="UTF-8" />
<title>Yangi vazifa</title>
</head>
<body>
<h1>Yangi vazifa qo'shish</h1>
<form action="/tasks" method="POST">
<p>
<label for="title">Sarlavha:</label>
<input type="text" id="title" name="title" />
</p>
<p>
<label for="priority">Muhimlik (1-5):</label>
<input type="number" id="priority" name="priority" />
</p>
<button type="submit">Saqlash</button>
</form>
</body>
</html>
Forma teglari forma asoslari darsida
ko’rilgan. Bu yerda ikki atribut muhim: action — ma’lumot qayerga
boradi, method — qaysi usul bilan.
express.urlencoded()
So’rov va javob darsida express.json() ni
uladik. Lekin HTML forma JSON yubormaydi — u boshqa formatdan
foydalanadi.
const express = require("express");
const path = require("path");
const app = express();
app.use(express.static(path.join(__dirname, "public")));
// Ikki format uchun ikki middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.post("/tasks", (request, response) => {
console.log(request.body);
response.send("Qabul qilindi");
});
app.listen(3000, () => {
console.log("Server ishga tushdi: http://localhost:3000");
});
Brauzerda http://localhost:3000/form.html ni ochib, formani to’ldiring
va Saqlash ni bosing. Server terminalida:
{ title: "Kitob o'qish", priority: '3' }
Hamma qiymat matn bo’lib keladi
Yuqoridagi natijaga qarang: priority: '3' — tirnoq ichida.
<input type="number"> bo’lsa ham, HTTP orqali hamma narsa matn
sifatida yuboriladi. Bu chalkashlik manbai:
const priority = request.body.priority; // "3"
console.log(priority + 1); // "31" — matn birikmasi
console.log(Number(priority) + 1); // 4 — to'g'ri
Shuning uchun tekshiruvning birinchi qadami — kerakli turga aylantirish.
Foydalanuvchi kiritganiga ishonmaslik
Tekshiruvni qo’lda yozish
Har xatoni alohida javob bilan qaytarish noqulay: foydalanuvchi birinchi xatoni tuzatadi, keyin ikkinchisini ko’radi. Yaxshisi — hamma xatoni bir yo’la yig’ish.
// Vazifa ma'lumotini tekshiradi, xatolar ro'yxatini qaytaradi
function validateTask(body) {
const errors = [];
const title = typeof body.title === "string" ? body.title.trim() : "";
const priority = Number(body.priority);
if (title === "") {
errors.push({ field: "title", message: "Sarlavha bo'sh bo'lmasin" });
} else if (title.length > 100) {
errors.push({ field: "title", message: "Sarlavha 100 belgidan oshmasin" });
}
if (Number.isNaN(priority)) {
errors.push({ field: "priority", message: "Muhimlik son bo'lishi kerak" });
} else if (priority < 1 || priority > 5) {
errors.push({ field: "priority", message: "Muhimlik 1 va 5 orasida bo'lsin" });
}
return errors;
}
Funksiya uch xil tekshiruvni qamraydi: mavjudlik (bo’shmi), uzunlik (juda uzun emasmi) va tur bilan oraliq (son va 1-5 orasidami).
typeof body.title === "string" tekshiruvi ham kerak: maydon umuman
yuborilmasa, body.title qiymati undefined bo’ladi va .trim()
chaqirilsa server yiqiladi.
Endi uni marshrutga ulaymiz:
let tasks = [];
let nextId = 1;
app.post("/tasks", (request, response) => {
const errors = validateTask(request.body);
if (errors.length > 0) {
// 400 — foydalanuvchi xatosi, qaysi maydon ekanini ham aytamiz
return response.status(400).json({ errors: errors });
}
const task = {
id: nextId,
title: request.body.title.trim(),
priority: Number(request.body.priority),
isDone: false,
};
nextId = nextId + 1;
tasks.push(task);
response.status(201).json(task);
});
Noto’g’ri ma’lumot bilan sinang:
curl -i -X POST http://localhost:3000/tasks \
-H "Content-Type: application/json" \
-d '{"title":"","priority":"999"}'
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
{"errors":[{"field":"title","message":"Sarlavha bo'sh bo'lmasin"},{"field":"priority","message":"Muhimlik 1 va 5 orasida bo'lsin"}]}
To’g’ri ma’lumot bilan:
curl -i -X POST http://localhost:3000/tasks \
-H "Content-Type: application/json" \
-d '{"title":"Kitob oqish","priority":"2"}'
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
{"id":1,"title":"Kitob oqish","priority":2,"isDone":false}
Javobdagi priority endi tirnoqsiz — u songa aylantirilib saqlandi.
Tekshiruvni middleware qilish
validateTask ni middleware shakliga o’tkazsak,
marshrut faqat o’z ishi bilan shug’ullanadi:
function checkTask(request, response, next) {
const errors = validateTask(request.body);
if (errors.length > 0) {
return response.status(400).json({ errors: errors });
}
next();
}
app.post("/tasks", checkTask, (request, response) => {
const task = {
id: nextId,
title: request.body.title.trim(),
priority: Number(request.body.priority),
isDone: false,
};
nextId = nextId + 1;
tasks.push(task);
response.status(201).json(task);
});
Marshrut funksiyasi qisqardi va tekshiruvni boshqa marshrutlarda
(masalan PUT /tasks/:id) qayta ishlatish mumkin bo’ldi.
Formadan keyin yo’naltirish
Forma brauzerdan yuborilganda JSON javob g’alati ko’rinadi — foydalanuvchi ekranda xom matn ko’radi. Odatda yo’naltirish qilinadi:
app.post("/tasks", checkTask, (request, response) => {
const task = {
id: nextId,
title: request.body.title.trim(),
priority: Number(request.body.priority),
isDone: false,
};
nextId = nextId + 1;
tasks.push(task);
// Saqlandi — foydalanuvchini ro'yxat sahifasiga yuboramiz
response.redirect("/tasks-list.html");
});
Nega shunday qilinadi: yo’naltirishsiz foydalanuvchi sahifani yangilasa,
brauzer POST so’rovini qayta yuboradi va bir xil vazifa ikki marta
qo’shiladi. Yo’naltirish bu muammoni yechadi, chunki oxirgi so’rov GET
bo’lib qoladi.
express-validator
Tekshiruvlar ko’payganda validateTask uzayib ketadi. Tayyor paket bu
ishni qisqartiradi:
npm install express-validator
const { body, validationResult } = require("express-validator");
app.post(
"/tasks",
body("title").trim().notEmpty().withMessage("Sarlavha bo'sh bo'lmasin"),
body("title").isLength({ max: 100 }).withMessage("Sarlavha 100 belgidan oshmasin"),
body("priority").isInt({ min: 1, max: 5 }).withMessage("Muhimlik 1 va 5 orasida bo'lsin"),
(request, response) => {
const result = validationResult(request);
if (!result.isEmpty()) {
return response.status(400).json({ errors: result.array() });
}
response.status(201).json({ message: "Vazifa qabul qilindi" });
}
);
Har body(...) qatori — alohida middleware. Ular tekshiruv natijasini
to’playdi, validationResult esa yig’ilgan xatolarni beradi.
| Yondashuv | Qachon qulay |
|---|---|
| Qo’lda yozilgan funksiya | Maydon kam, qoidalar oddiy |
express-validator |
Maydon ko’p, qoida murakkab |
Qo’lda yozishni avval o’rganish foydali: paket parda ortida aynan shu ishni bajaradi.
Amaliy mashq
express-app loyihasida davom eting:
public/form.htmldatitlevaprioritymaydonli forma yarating;express.urlencoded({ extended: true })ni ulab, formani yuboring varequest.bodyni terminalda ko’ring;nameatributini bitta maydondan olib tashlang — urequest.bodyda yo’qolishini tasdiqlang, so’ng qaytaring;validateTaskfunksiyasini yozib, bo’sh sarlavha vapriority=999bilan400javobini oling;- Tekshiruvni
checkTaskmiddleware’iga o’tkazib, marshrutga ulang; curlorqali brauzerni chetlab o’tib bo’shtitleyuboring va server tekshiruvi baribir ishlashini ko’ring.
6-qadam darsning asosiy g’oyasini isbotlaydi: HTML’dagi required
to’sib qololmaydi, server tekshiruvi esa to’sadi.
Qisqacha xulosa
- HTML forma JSON emas,
x-www-form-urlencodedformatida yuboradi —express.urlencoded()kerak. request.bodykalitlarinameatributidan olinadi;namebo’lmasa maydon yuborilmaydi.- HTTP orqali kelgan hamma qiymat matn — sonni
Number()bilan aylantiring. - Brauzerdagi
requiredhimoya emas:curluni chetlab o’tadi, tekshiruv serverda takrorlanishi shart. - Xatolarni massivga yig’ib,
fieldvamessagebilan qaytaring — frontend ularni maydonlarga bog’lay oladi. - Noto’g’ri ma’lumotga
400javobi beriladi. - Tekshiruvni middleware qilsangiz, uni bir nechta marshrutda qayta
ishlatasiz;
express-validatorshu ishni qisqartiradi.
Keyingi darsda EJS shabloni — JSON o’rniga to’laqonli HTML sahifa qaytarish va uni xavfsiz to’ldirish.