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,