emirhanHCL 1
emirhanHCL
kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
farkmt2official 1
farkmt2official
mannaxxx 1
mannaxxx
Bvural41 1
Bvural41
Agora Metin2 1
Agora Metin2
Hikaye Ekle

[NODE JS] POST Isteginden Body Verisi Alma

nodejs.png


[NODE JS] POST Isteginden Body Verisi Alma​


Selam arkadaslar, bugun Node.js'te HTTP POST isteklerinden body verisini nasil alacagimizi ogrenecegiz. GET isteklerinde parametreler URL'de yer aliyor ama POST isteklerinde veri request body'sinde gonderiliyor. Bu veriyi okumak Node.js'te biraz farkli bir yaklasim gerektiriyor cunku veri stream olarak gelir ve sizin birlestirmeniz gerekir.

Body Neden Stream Olarak Gelir?​


Node.js'te request nesnesi bir Readable stream'dir. Yani veri parcalar (chunks) halinde gelir, hepsi bir anda degil. Bu tasarim buyuk dosya upload'larinda ve buyuk veri gonderimlerinde bellek verimli calismayi saglar. Eger Node.js tum body'yi otomatik olarak bellege alsa, 1 GB'lik bir dosya upload'u sunucunuzu cokerterdi. Ama bu yaklasim basit bir JSON body okumak icin biraz fazla kod yazmak anlamina da geliyor. Express.js bu yuzden body-parser middleware'ini kullanir.

Ben ilk baslarken neden req.body diye dogrudan okuyamiyorum diye cok sinirlanmistim. Ama mantigi anladiktan sonra bunun ne kadar dogru bir tasarim oldugunu gordum.

JavaScript:
const http = require('http');
const { URL } = require('url');
const { StringDecoder } = require('string_decoder');

// Yontem 1: Event bazli body okuma
function bodyOkuTemel(req) {
    return new Promise((resolve, reject) => {
        const chunks = [];
        let toplamBoyut = 0;
        const MAX_BOYUT = 1024 * 1024; // 1 MB limit

        req.on('data', (chunk) => {
            toplamBoyut += chunk.length;

            // Boyut kontrolu (guvenlik)
            if (toplamBoyut > MAX_BOYUT) {
                req.destroy();
                reject(new Error('Body boyutu limiti asildi (max 1MB)'));
                return;
            }

            chunks.push(chunk);
        });

        req.on('end', () => {
            const body = Buffer.concat(chunks).toString('utf8');
            resolve(body);
        });

        req.on('error', (err) => {
            reject(err);
        });
    });
}

// Yontem 2: JSON body okuma (tipli)
async function jsonBodyOku(req) {
    const contentType = req.headers['content-type'] || '';

    if (!contentType.includes('application/json')) {
        throw new Error('Content-Type application/json olmalidir');
    }

    const rawBody = await bodyOkuTemel(req);

    if (!rawBody) {
        return {};
    }

    try {
        return JSON.parse(rawBody);
    } catch (e) {
        throw new Error('Gecersiz JSON formati: ' + e.message);
    }
}

// Yontem 3: Form data okuma (application/x-www-form-urlencoded)
async function formBodyOku(req) {
    const rawBody = await bodyOkuTemel(req);
    const params = new URLSearchParams(rawBody);
    const sonuc = {};

    for (const [anahtar, deger] of params) {
        if (sonuc[anahtar]) {
            if (Array.isArray(sonuc[anahtar])) {
                sonuc[anahtar].push(deger);
            } else {
                sonuc[anahtar] = [sonuc[anahtar], deger];
            }
        } else {
            sonuc[anahtar] = deger;
        }
    }

    return sonuc;
}

// Sunucu
const sunucu = http.createServer(async (req, res) => {
    const url = new URL(req.url, `http://${req.headers.host}`);

    // JSON cevap helper
    const json = (kod, veri) => {
        res.writeHead(kod, { 'Content-Type': 'application/json; charset=utf-8' });
        res.end(JSON.stringify(veri, null, 2));
    };

    try {
        // POST /api/kayit - JSON body
        if (url.pathname === '/api/kayit' && req.method === 'POST') {
            const body = await jsonBodyOku(req);

            // Dogrulama
            const hatalar = [];
            if (!body.ad) hatalar.push('ad zorunlu');
            if (!body.email) hatalar.push('email zorunlu');
            if (!body.sifre) hatalar.push('sifre zorunlu');
            if (body.sifre && body.sifre.length < 6) hatalar.push('sifre en az 6 karakter');

            if (hatalar.length > 0) {
                json(400, { basarili: false, hatalar });
                return;
            }

            // Kayit islemi (simule)
            const kullanici = {
                id: Date.now(),
                ad: body.ad,
                email: body.email,
                olusturma: new Date().toISOString()
            };

            json(201, { basarili: true, kullanici });
        }

        // POST /api/form - Form data
        else if (url.pathname === '/api/form' && req.method === 'POST') {
            const body = await formBodyOku(req);
            json(200, { basarili: true, alinanVeri: body });
        }

        else {
            json(404, { hata: 'Bulunamadi' });
        }
    } catch (error) {
        json(error.message.includes('limit') ? 413 : 400, {
            basarili: false,
            hata: error.message
        });
    }
});

sunucu.listen(3000, () => {
    console.log('Sunucu http://localhost:3000 adresinde calisiyor');
});

Content-Type'a Gore Islem​


Gelen istegin Content-Type basligina gore farkli parse yontemleri kullanmaliyiz. application/json icin JSON.parse, application/x-www-form-urlencoded icin URLSearchParams ve multipart/form-data icin ozel parser gerekir. Multipart veriler icin genelde formidable veya multer gibi kutuphaneler kullanilir cunku bu formati elle parse etmek cok karmasiktir.

Tecrubeme gore, body okuma isleminde en cok yapilan hata boyut limiti koymamaktir. Limitisiz body okuma, saldirganin sunucunuzun bellegini tuketmesine olanak tanir. Her zaman makul bir boyut limiti belirleyin. Ayrica Content-Type kontrolu de onemlidir, beklemediginiz bir formatta veri gelirse reddedin. Bu kadar, bir sonraki konuda HTTP status kodlarini inceleyecegiz!
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst