JavaScript Blog

Async request body function in Node.JS

2022. június 07. - BATZOZOO

A Node.JS ajánlása szerint többféle módon kaphatjuk el a frontend által a requestben küldött body-t Node.JS-ben. 

A connection-callback során átadott kérelem objektum egy stream, egy adatfolyam magyarul. Tehát ezt a folyamot kell figyelnünk, egy listenerrel. A req.on data és a req.on end eseményekre kell feliratkoznunk. A data során a request-eket darabokban (angolul chunk-okban) kapjuk meg. A data eseményben ezeket a darabokat hozzáfűzzük stringként egy változóhoz (a példában ez data, hogy egyértelmű legyen). Az end során megkapjuk a JSON stringet, amit parse-lünk, így megkapjuk az objektumot, amit már lehetőségünk van kiíratni vagy akármilyen műveletet elvégeztetni vele.

Tehát a kód így néz ki.


//Esemény feliratkozós változat req.on-nal
const server = http.createServer((req, res) => {
  let data = ''; // A data változó dekralálása (string)
  req.on('data', chunk => {
    data += chunk; // A data eseményben a chunk-okat hozzáadjuk a data változóhoz
  });
  req.on('end', () => {
    console.log(JSON.parse(data)); // Az end eseménynél parse-ljük a datat, így megjapjuk a data objektumot, amivel dolgozhatunk.
    res.end();
  });
});

Kicsit a fetch.then(....)-re hasonlít.

Van egy async változata is a dolognak for await of ciklussal.


// Aszinkron változat for await of-al
const server = http.createServer(async (req, res) => {
  const buffers = []; // Buffer tömb deklaráció

  for await (const chunk of req) {
    buffers.push(chunk); A kapott schunk-okat a buffer tömbbe pusholjuk async módon
  }

  const data = Buffer.concat(buffers).toString(); // A kapott tomböt összeolvasszuk egy string-be

  console.log(JSON.parse(data)); // A stringet objektumra parse-ljül
  res.end();
});

 

Ez utóbbit szépen ki lehet szedni async/await módon, de az elsőnél szükségünk lesz egy kis csavarra, hogy kitehessük külön funkcióba. A megoldás, hogy promise-é kell alakítani. 


// Aszinkron változat a req.on esemény feliratkozások promise-é alakításával
const readStream = (req) =>
  new Promise((resolve, reject) => {
    let buffer = "";
    req.on("data", (data) => (buffer += data.toString()));
    req.on("close", () => resolve(buffer));
    req.on("end", () => resolve(buffer));
  });

 

A lényege, hogy az egész pakkot beledobjuk egy függvénybe (én a readStream-et adtam neki névnek), annak átadjuk a req-t és egy új promise példánnyal térünk vissza. Ezt a függvényt bármelyik aszinkron függvényben fel tudjuk használni és így megkapjuk a beküldött req body-t

Nézzünk akkor egy kis gyakorlati példát. Így néz ki az egész egy komplett Node.JS szerverben:


//Server.js
const http = require("http");
http.createServer(main).listen(8080, () => console.log("Server started..."));

const readStream = (req) =>
  new Promise((resolve, reject) => {
    let buffer = "";
    req.on("data", (data) => (buffer += data.toString()));
    req.on("close", () => resolve(buffer));
    req.on("end", () => resolve(buffer));
  });

async function main(req, res) {
  const reqBody = await readStream(req);
  const response =
    reqBody === ""
      ? "I did not get body req"
      : JSON.stringify({ yourReqbody: JSON.parse(reqBody) });
  res.setHeader("Access-Control-Allow-Origin", "https://cdpn.io");
  res.setHeader("Content-Type", "application/json");
  res.write(response);
  res.end();
}

 

Itt pedig a frontend kód:


async function postBodyToServer(){
	const options = {
		method: "POST",
		body: JSON.stringify({
			teszt: "teszt",
			teszt2: "teszt2"
		})
	}
	const response = await fetch("https://5i9ici.sse.codesandbox.io/", options)
	const data = response.json()
	return data;
}

async function init(){
	const data = await postBodyToServer();
	console.log(data)
	document.querySelector('#root').innerHTML = Template(data);
	
}

function Template(data){
	return `<pre>${JSON.stringify(data, null, "\t")}</pre>`
}

init()

See the Pen POST BODY TO STREAM SERVER by Bzozoo (@bzozoo) on CodePen.

 

 A frontend elküldi fetch-el POST metódusban a Node.JS szervernek az adatokat body-ban, majd a szervertől ezt egy yourReqbody kulcsú objektumban kapjuk vissza, amit kiír a frontend a root id-vel rendelkező divbe.

A bejegyzés most nem tárgyalta az Express-el kapcsolatos body req-t, ez csak szimpla Node.JS RES, REQ handler funkcióval.

Ha vannak még további ötleteid hogyan nyerhető ki a request body a req stream-ből, vagy esetleg valami kérdésed van, akkor megírhatod kommentben,

A bejegyzés trackback címe:

https://jscript.blog.hu/api/trackback/id/tr7617850751

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása