Search code examples
javascriptnode.jshttppostserver

HTTP Request end event will not trigger (Node.js)


I am writing a simple server and webpage in Node.js. I am trying to process a POST request and get the data from the request body. I have been following this example code, which works fine when I run it:

const http = require('http');

http.createServer((request, response) => {
  let body = [];
  request.on('data', (chunk) => {
    body.push(chunk);
  }).on('end', () => {
    body = Buffer.concat(body).toString();
    console.log("Received "+request.method+" "+request.url); //note method is a string
    //the next line prints the http headers formatted for humans
    //it is still verbose so you may want it commented out
    //console.log("HTTP Headers "+JSON.stringify(request.headers,null,2));
    console.log(body);
    response.end(body);
  });
  
}).listen(8080);

When I run this code and send the request, I get the proper output, which is just the body of the request which contains a JSON string: Received POST /book/686545342424 {"isbn":"686545342424","title":"testbook","price":"16"}

However, in the server I am writing, the same code does not work. I copied and pasted it to make sure there were no differences, and it still doesn't work for me. Here is my code. The relevant section is after if(req.method === "POST"):

const fs = require('fs');
const http = require('http');

const data = fs.readFileSync(process.argv[3]);
let books = JSON.parse(data);

http.createServer((req, res) => {
    console.log(req.url);
    if(req.url === '/client.html') {
        let page = fs.readFileSync('client.html');
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.end(page);
        console.log(req.header);
    } else if (req.url === '/test.html') {
        let page = fs.readFileSync('test.html');
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.end(page);
        console.log(req.header);
    } else if (req.url.substring(0,6) === "/book/") {
        if(req.method === "GET") {
            let book = 0;
            for(i=0;i<books.length;i++) {
                if(books[i].isbn === req.url.substring(6)) {
                    book = books[i];
                }
            }
            if(book === 0) {
                res.writeHead(404, {'Content-Type': 'text/plain'});
                res.end();
            } else {
                res.writeHead(200, {'Content-Type': 'application/json'});
                res.end(JSON.stringify(book));
                console.log(res.header+"0");
            }
            
        } else if(req.method === "POST") {
            let body = [];
            req.on('data', (chunk) => {
                body.push(chunk);
            }).on('end', () => {
                console.log("WE MADE IT");
                body = Buffer.concat(body).toString();
                console.log("Received "+req.method+" "+req.url); //note method is a string
                //the next line prints the http headers formatted for humans
                //it is still verbose so you may want it commented out
                console.log("HTTP Headers "+JSON.stringify(request.headers,null,2));
                console.log(body);
                response.end(body);
            });
            console.log(body);
            let book = JSON.parse(body);
            
            let found = false
            for(i=0;i<books.length;i++) {
                if(books[i].isbn === req.url.substring(6)) {
                    found = true;
                }
            }
            if(!found) {
                books.push(book);
                res.writeHead(201, {'Content-Type': 'text/plain'})
                res.end();
            } else {
                res.writeHead(400, {'Content-Type': 'text/plain'})
                res.end();
            }
        }
    } else {
        let page = "404 File Not Found";
        res.writeHead(404, {'Content-Type': 'text/html'});
        res.end(page);
    }
  
}).listen(process.argv[2]);

When I run this server and send the request, the array "body" remains empty. I think I have figured out that the code is not entering the block that is triggered by the "end" event, but I can't figure out why that would be. The exact same code with the exact same request works in the example program but not in mine. I'm assuming there is something elsewhere in my code that is affecting the result, but I don't know what that would be. I'm a bit new to Javascript.

I have looked at other answers to questions about the end event not triggering, but none of them are quite the same. I tried adding another function on data chunks before the end, just in case the first one wasn't going all the way to the end for some reason, but that didn't change anything. I can add my client code as well if that would be helpful, but I don't think that's part of the problem since it works with the example server I was working with.

EDIT: I had someone else run my code on a different machine, and they could not replicate the issue. The "end" event was triggered, and the code in the end block happened. I don't understand why this would be


Solution

  • i changed the example to become more easier and understandable

    first thing first this no good way to send post request /book/686545342424 it must be /book if you want send put request you can do like /path/id

    use postman application to send request to http://localhost:8000

    get request it dose not have any body but post request has obejct body

    {
    "title":"algbera",
    "price":200,
    "isbn":784368367528923
    }
    

    and the code for sever

    const http = require('http');
    
    const books = [
    {
     isbn: 686545342424, title: "testbook", price: 16
    },
    {
     isbn: 980000002008, title: "demobook", price: 10
    },
    ];
    
    http.createServer((request, response) => {
    console.log("Received " + request.method + " " + request.url);
    
    if (request.method === "GET") {
    response.setHeader("Content-Type", "application/json");
    response.writeHead(200);
    response.end(JSON.stringify(books));
    
    } else if (request.method === "POST") {
    let body = [];
    request.on('data', (chunk) => {
      body.push(chunk);
     }).on('end', () => {
      body = Buffer.concat(body).toString();
      const newBook = JSON.parse(body);
      let found = false
      for(i=0;i<books.length;i++) {
        if(books[i].isbn === newBook.isbn ) {
          found = true;
        }
       }
       if(!found) {
        books.push(newBook);
        response.setHeader("Content-Type", "application/json");
        response.writeHead(201);
        response.end('add new book');
        } else {
        response.setHeader("Content-Type", "application/json");
        response.writeHead(400);
        response.end('book already exist');
        }
    
       });
       }
    
    
     }).listen(8000);