Reputation: 85
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.
Upvotes: 1
Views: 249
Reputation: 91
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
Upvotes: 0
Reputation: 586
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".
Upvotes: 1