Request and Response Headers - aakash14goplani/FullStack GitHub Wiki

Request object is the object nodejs generated for us with all the data of the incoming request. Similarly Response object is the object that you can update/manipulate per requirements and send to end source.

Topics Covered


Request Structure and Methods

  • It has several methods, of which three are important: method, url and headers
    const server = http.createServer((req, res) => {
       console.log('req url :', req.url);
       console.log('res headers :', req.headers);
       console.log('req method :', req.method);
    });

Sending Responses

  • We need to set headers to sent response:
const server = http.createServer((req, res) => {
    res.setHeader('Content-Type', 'text/html');
    res.setHeader('Aakash', 'Goplani');
    res.write('<html>');
    res.write('<head><title>Node JS Basics</title></head>');
    res.write('<body>');
    res.write('<h1>Node JS Tutorial</h1>');
    res.write('</body>');
    res.write('</html>');
    res.end();
});
server.listen(4200, 'localhost');
  • Now if we go to http://localhost:4200 we'll see the corresponding response.

  • Note: We now also need to tell node once we're done with creating that response and we do this by calling end(). We can still call write but this will result in an error because we must not change the response after we ended it because this is basically the part where we will send it back to the client, nodejs will send it back to the client.

  • List of request and response headers


Routing Requests

  • Let's say for / or /aakash, we want to load a page and perform some action. We can do this by parsing the url.
const server = http.createServer(req, res) => {
   const url = req.url;
   if (url === "/" || url === "/aakash") {
        res.write('<html>');
        ...
        res.write('</html>');
        return res.end();
    }
   ...
}
  • If we want to intercept a request at / and the method must be POST
const server = http.createServer(req, res) => {
   const url = req.url;
   const method = req.method;
   if (url === "/" && method === "POST") {
        res.write('<html>');
        ...
        res.write('</html>');
        return res.end();
    }
   ...
}
  • Importance of return statement:
    • This is not required to return a response but to return from this anonymous function.
    • And we must do this because we must not call any other res.write()'s or res.setHeader()'s but this what happens if we not return because then it would just continue execution with remaining lines.

Redirecting Requests

  • To redirecting a request, we set the response code to 302 and set the header Location to the target URL where the user should be redirected to, in this case, it is /.
    const server = http.createServer(req, res) => {
       const url = req.url;
       const method = req.method;
       if (url === "/" && method === "POST") {
           res.statusCode = 302;
           res.setHeader('Location', '/');
           return res.end();
        }
       ...
    }
  • And important, as before return this so that we don't execute remaining lines otherwise we will get an error.

Parsing Request Data

  • The incoming data is basically sent as a stream of data. The request is simply read by Node in chunks in multiple parts and in the end at some point of time it's done/completed then we can start working on these individual chunks.

  • To work with these incoming chunks, you use a buffer which is simply a construct that allows you to hold multiple chunks and work with them.

  • We do this by going to our request and registering an event listener. The event I want to listen to here is the data event that will be fired whenever a new chunk is ready to be read. The second argument here is a function that should be executed for every data event i.e. for every incoming data piece.

const body = [];
req.on('data', (chunk) => {
   body.push(chunk);
});
  • Now we need to register another event listener and that is the end listener, this will be fired once it's done parsing the incoming requests data or the incoming requests in general. Here it will again execute a function we define as a second argument and in this function, we can now rely on all the chunks being read in and they're all stored in the body now.
return req.on('end', () => {
   const parsedBody = Buffer.concat(body).toString();
   fs.writeFile('message.txt', parsedBody.split('=')[1], (error) => {
      if (!error) {
         res.statusCode = 302;
         res.setHeader('Location', '/');
         return res.end();
      } else {
         console.log('error occurred: ', error);
      }
   });
});
  • Now to interact with this we now need to buffer them. So here I'll now create a new constant, parsedBody and there I will use the buffer object which is available globally, to concat my data chunks. So this will in the end create a new buffer and add all the chunks from inside my body to it.

Exporting a Module

/* file 1 (routes.js): exporting */
const routeHandling = (req, res) => {...});
...
module.exports = routeHandling;

/* file 2 (app.js): importing */
const routes = require('./routes');
const server = http.createServer(routes);

/* You can also export module as an Object */
module.exports.handler = routeHandling
module.exports.text = "text"
module.exports.aakash = "goplani"

...

const server = http.createServer(routes.handler); // multiple export
console.log(routes.text + ' ...' + routes.aakash);
⚠️ **GitHub.com Fallback** ⚠️