Home > Software engineering >  Can't get req.body with client fetch() and Node.js
Can't get req.body with client fetch() and Node.js

Time:08-20

I have simple app.js for Node.js under localhost:3000

app.js:

let http = require('http');

http.createServer((req, res) => {
    res.writeHead(200);
    let response;
    if(~req.url.indexOf('post')) {
        response = req.body.content;
    } else {
        response = '<script src="http://localhost/fetch.js"></script>';
    }
    res.end(response);
}).listen(3000);

The file fetch.js is placed on my another local server and is successfully enqueued to the page

fetch.js:

read('http://localhost:3000/?post').then((response) => {
    console.log(response);
});
async function read(url) {    
    const response = await fetch(url, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json;charset=utf-8',
        },
        body: JSON.stringify({
            content: 'Text'
        })
    });
    return response.text();
}

So I render HTML with fetch.js which then send POST request to the same page, but with a query ?post

However, when I run node app.js I get the error

Can not read property 'content' of undefined

So I don't get req.body

Why and how to resolve?

CodePudding user response:

i think you are missing parser for your http server, there is no body because you actually didn't parse the body.

assemble the chunks like below then parse it as the header sais.

this is my work for myself

private parseBody(req: IncomingMessage) {
    return new Promise((resolve, reject) => {
      const chunks: any[] = []

      req.on("data", (chunk) => {
        chunks.push(chunk)
      })

      req.on("end", () => {
        const data = Buffer.concat(chunks)

        switch (req.headers["content-type"]) {
          case "application/json":
            resolve(this.parseJson(data.toString()))
            break

          case "application/x-www-form-urlencoded":
            resolve(this.parseUrlEncoded(data.toString()))
            break

          default:
            resolve({})
        }
      })
    })

http server is very abstract and doesn't support anything basicly, i suggest using express or fastify.

working example: https://frontendguruji.com/blog/how-to-parse-post-request-in-node-js-without-expressjs-body-parser/

CodePudding user response:

Ok, thanks to @Fide. The link he posted has the answer:

let http = require('http');

http.createServer((req, res) => {
    if(~req.url.indexOf('post')) {
        let body;
        req.on('data', function(data) {
            body = data;
        })
        req.on('end', function() {
            res.writeHead(200);
            res.end(body);
        })
    } else {
        res.writeHead(200);
        res.end('<script src="http://localhost/fetch.js"></script>');
    }
}).listen(3000);
  • Related