简体   繁体   中英

js/ nodejs basic beginner server for POST method using request.on() and querystring.parse()

I'm starting to learn some nodejs in my web classes after javascript to make some simple servers, and with this example below:

var http = require('http');
var url = require('url');
var querystring = require('querystring');


function onRequest(request, response) {

    if (request.method == 'POST') {
        var body = '';

        request.on('data', function (data) {
            body += data;  // data sent via http protocol will always be sent as a string and can be concatenated
            // if body > 1e6 === 1* Math.pow(10,6) ~~~ 1MB
            // flood attack or faulty client
            // (code 413: request entity too large), kill request
            if (body.length > 1e6) {
                response.writeHead(413, {'Content-Type':'text/plain'}).end();
                request.connection.destroy();
            }
        });            // end of data communication: body will contain all the parameters of the query 

        request.on('end',function(){
            var POST = querystring.parse(body);
            // now to get the different parameters use // POST.<field name>  e.g. POST.user
            response.end('Hello, ' + POST.firstname + ' ' + POST.lastname);

        });
    }


}

var server = http.createServer(onRequest);

server.listen(3000);

I have understood up to this point but have trouble looking up and understanding the request.on() and querystring.parse() portions of this code. I'll highlight them for more clarity below the exact parts I'm confused with.

1) request.on()

So I've read that request.on('data') will have nodejs set a listener for the event of receiving a chunk of data. So with the example above this part:

request.on('data', function (data) {
                body += data;  
                if (body.length > 1e6) {
                    response.writeHead(413, {'Content-Type':'text/plain'}).end();
                    request.connection.destroy();
                }

It's taking a second parameter as a callback function that takes the first parameter 'data' again. This is what I'm confused with, what is it trying to do here with the second parameter?

2) request.on('end') and querystring.parse()

I read that request.on('end') will have nodejs set a listener for the signal that the data upload completed , so this code below:

request.on('end',function(){
                var POST = querystring.parse(body);
                // now to get the different parameters use // POST.<field name>  e.g. POST.user
                response.end('Hello, ' + POST.firstname + ' ' + POST.lastname);

            }

Inside request.on('end') we make a new variable called POSTand set it equal to querystring.parse(body) with body being the previous variable of all the data combined. How does it go from this querystring.parse(body) and apply .firstname on it ( POST.firstname ) and access that component of it?

Thanks in advance.

For your first question:

It's taking a second parameter as a callback function that takes the first parameter 'data' again. This is what I'm confused with, what is it trying to do here with the second parameter?

So what you're doing here is defining a listener function to be called each time the request fires a data event. You may be able to see it clearer in the following manner:

request.on('data', onChunkReceived)

function onChunkReceived (data) {
  body += data

  if body > 1e6 === 1* Math.pow(10,6) ~~~ 1MB
    if (body.length > 1e6) {
      response.writeHead(413, {'Content-Type':'text/plain'}).end();
      request.connection.destroy();
    }
}

What you're doing is defining a function, which takes a data parameter; don't get too hung up in the fact that the event name and the parameter name that was chosen are the same; there's no reason you couldn't name it whatever you want:

request.on('data', onChunkReceived)

function onChunkReceived (chunk) {
  body += chunk

  if body > 1e6 === 1* Math.pow(10,6) ~~~ 1MB
    if (body.length > 1e6) {
      response.writeHead(413, {'Content-Type':'text/plain'}).end();
      request.connection.destroy();
    }
}

...will act exactly the same way. So again: data is the name of the event, and you're defining a function that receives each chunk of data as the server receives it; in your example above the function is just anonymous function that is in-line, as I've reformatted the snippet above it's a separate named function.

Now to your second question:

Inside request.on('end') we make a new variable called POSTand set it equal to querystring.parse(body) with body being the previous variable of all the data combined. How does it go from this querystring.parse(body) and apply .firstname on it (POST.firstname) and access that component of it?

The querystring.parse method takes a string in a specific format, and parses it into a Javascript object. The Node.js docs on querystring explain it far better than I will be able to here. So, I can only assume that the example you're working from expects that the body will be in a specific format, that is form encoded meaning that it's in the format of the following:

firstname=Dan&lastname=Takahashi

When you call querystring.parse on that string, you'll be returned an object that looks like:

POST = {
  "firstname": "Dan",
  "lastname": "Takahashi"
}

Which you can then address as you say above: POST.firstname which will be "Dan" and POST.lastname , which will be "Takahashi".

Questions 1 & 2 deal with the http request data stream and allow you to inject your code to do custom activities like save the stream to a buffer/var for later use.

If you want to query the POST parameters you can simply use the bodyparser node module https://github.com/expressjs/body-parser

to query the parameters using object dot notation. For example req.body.form_field_name

body-parser is a nice module to use to get quick access to data passed along in a POST/PUT method.

Express keeps the raw body data hidden and you'll need to use a module similar to body-parser to get access. Please note this is a read only copy of the body content.

Cheers.

PS if body-parser doesn't address your immediate need, check out

  1. github.com/stream-utils/raw-body
  2. github.com/moscartong/express-rawbody

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM