Node.js va Express

Fayl tizimi va HTTP server

Endi Node.js'ning haqiqiy kuchini ko'ramiz: fayllar bilan ishlash va o'z veb-serveringizni yaratish. Bu narsalar brauzerda mumkin emas edi โ€” Node.js'da esa bir necha qator kod bilan amalga oshiriladi. Ushbu darsda fs, path va http modullarini o'rganamiz.

fs moduli: fayllarni o'qish va yozish

fs (file system) โ€” fayl tizimi bilan ishlash moduli. U fayllarni o'qish, yozish, o'chirish, papkalar yaratish va boshqa amallarni bajaradi. Bu o'rnatilgan modul, shuning uchun o'rnatish shart emas:

const fs = require('fs');

fs modulining aksariyat funksiyalari ikki ko'rinishga ega: sinxron (bloklaydigan) va asinxron (bloklamaydigan).

Sinxron o'qish/yozish

Sinxron funksiyalar nomi Sync bilan tugaydi. Ular fayl operatsiyasi tugaguncha kutadi va natijani darhol qaytaradi:

const fs = require('fs');

// Faylga yozish (agar fayl bo'lmasa, yaratiladi):
fs.writeFileSync('salom.txt', 'Salom, dunyo!');

// Fayldan o'qish:
const matn = fs.readFileSync('salom.txt', 'utf8');
console.log(matn); // Salom, dunyo!

Diqqat: readFileSyncga ikkinchi argument sifatida 'utf8' kodlashni berish muhim. Aks holda natija matn emas, xom Buffer (baytlar) bo'ladi.

Sinxron funksiyalar kutish davomida butun dasturni bloklaydi. Katta fayllar yoki serverda ular yomon tanlov โ€” chunki server bloklanib, boshqa so'rovlarga javob bera olmay qoladi. Ular faqat dastur ishga tushayotgan paytda (konfiguratsiya o'qish) yoki kichik skriptlarda ishlatiladi.

Asinxron o'qish/yozish

Asinxron funksiyalar bloklamaydi. Ular natija tayyor bo'lganda callback chaqiradi. Callback'ning birinchi argumenti โ€” xatolik (bo'lmasa null), ikkinchisi โ€” natija:

const fs = require('fs');

fs.writeFile('salom.txt', 'Salom!', (err) => {
  if (err) {
    console.error('Yozishda xato:', err);
    return;
  }
  console.log('Fayl yozildi');

  fs.readFile('salom.txt', 'utf8', (err, data) => {
    if (err) {
      console.error('O'qishda xato:', err);
      return;
    }
    console.log('Fayl mazmuni:', data);
  });
});

Callback'lar ichma-ich joylashganda kod o'qish qiyinlashadi ("callback do'zaxi"). Shuning uchun zamonaviy kodda Promise versiyasidan foydalaniladi. U fs.promises orqali mavjud:

const fs = require('fs').promises;

async function ishla() {
  await fs.writeFile('salom.txt', 'Salom!');
  const data = await fs.readFile('salom.txt', 'utf8');
  console.log(data);
}

ishla();
Zamonaviy Node.js kodida fs.promises va async/await kombinatsiyasi tavsiya etiladi โ€” u toza, o'qilishi oson va xatoliklarni try/catch bilan boshqarishga imkon beradi.

path moduli

Fayl yo'llari bilan ishlashda operatsion tizimlar orasida farq bor: Windows \, Linux/Mac esa / ishlatadi. path moduli bu farqlarni avtomatik hal qiladi va yo'llarni xavfsiz birlashtiradi:

const path = require('path');

// Yo'llarni to'g'ri birlashtirish:
const toliqYol = path.join('papka', 'ichki', 'fayl.txt');
console.log(toliqYol); // papka/ichki/fayl.txt

// Fayl nomini ajratish:
console.log(path.basename('/uy/user/rasm.png')); // rasm.png

// Kengaytmani olish:
console.log(path.extname('rasm.png')); // .png

// Papkani olish:
console.log(path.dirname('/uy/user/rasm.png')); // /uy/user
Node.js'da __dirname โ€” joriy fayl joylashgan papkaning to'liq yo'lini beruvchi maxsus o'zgaruvchi. Uni path.join bilan birlashtirib, ishonchli mutlaq yo'l hosil qilinadi: path.join(__dirname, 'data', 'users.json').

http moduli: birinchi server

Endi eng qiziq qismi โ€” o'z veb-serveringizni yaratamiz! http moduli bu uchun barcha kerakli narsani beradi. http.createServer yangi server yaratadi:

const http = require('http');

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain; charset=utf-8');
  res.end('Salom, bu mening serverim!');
});

server.listen(3000, () => {
  console.log('Server ishga tushdi: http://localhost:3000');
});

Bu faylni node server.js bilan ishga tushiring va brauzerda http://localhost:3000 manzilini oching. "Salom, bu mening serverim!" degan matnni ko'rasiz. Tabriklaymiz โ€” sizda o'z veb-serveringiz bor!

req va res obyektlari

createServerga berilgan funksiya har bir so'rov kelganda ikkita argument bilan chaqiriladi:

Kiruvchi so'rov ma'lumotini ishlatib, turli manzillarga turli javob berish mumkin (oddiy marshrutlash):

const http = require('http');

const server = http.createServer((req, res) => {
  console.log('So'rov:', req.method, req.url);

  if (req.url === '/') {
    res.end('Bosh sahifa');
  } else if (req.url === '/about') {
    res.end('Biz haqimizda');
  } else {
    res.statusCode = 404;
    res.end('Sahifa topilmadi');
  }
});

server.listen(3000);

JSON javob qaytarish uchun sarlavhani to'g'ri sozlab, obyektni matnga o'giriladi:

const server = http.createServer((req, res) => {
  res.setHeader('Content-Type', 'application/json');
  const malumot = { ism: 'Ali', yosh: 25 };
  res.end(JSON.stringify(malumot));
});

Portni tinglash

server.listen(port) serverni ma'lum bir portda tinglashga majbur qiladi. Port โ€” bu kompyuterdagi "eshik raqami"; turli servislar turli portlarda ishlaydi:

// Port va manzilni tinglash, tayyor bo'lganda xabar berish:
server.listen(3000, () => {
  console.log('Server 3000-portda ishlamoqda');
});
Agar port allaqachon band bo'lsa, EADDRINUSE xatosini olasiz. Bunday holatda boshqa portni tanlang yoki o'sha portni band qilib turgan eski jarayonni to'xtating. Serverni to'xtatish uchun terminalda Ctrl+Cni bosing.
Ko'rib turganingizdek, sof http moduli bilan marshrutlash qo'lda, sertifikatsiz yoziladi โ€” bu tez charchatadi. Aynan shu sabab keyingi darslarda Express freymvorkiga o'tamiz: u bu ishlarni ancha soddalashtiradi.

Xulosa