I’m reading a tutorial in http://www.nodebeginner.org and I have a strange behavior in data output. I know, there’s a similar question on Stackoverflow but there’s no answer. So I have this code of web-server:
//server.js
var http = require('http')
var url = require('url')
function start(route, handle) {
function onRequest(request, response) {
var postData = ""
var pathname = url.parse(request.url).pathname
console.log("Request for " + pathname + " recieved.")
request.setEncoding('utf8')
request.addListener("data", function(postDataChunk) {
postData += postDataChunk
console.log("Recieved POST data chunk '" + postDataChunk +"'.")
})
request.addListener("end", function() {
route(handle, pathname, response, postData)
})
var content = route(handle, pathname, response)
}
http.createServer(onRequest).listen(80, '192.168.1.34')
console.log("Server has started")
}
exports.start = start
Code of router.js which calls requestHandler.upload – my buggy function
//router.js
function route(handle, pathname, response, postData) {
console.log("About to route a request for " + pathname)
if (typeof handle[pathname] === 'function') {
handle[pathname](response, postData) //calls requestHandler.upload
} else {
console.log("No request handler found for " + pathname)
response.writeHead(404, {'Content-Type' : 'text/plain'})
response.write("404 Not found")
response.end()
}
}
And the code of requestHandler.upload
//requestHandler.js
function upload(response, postData) {
console.log("Request handler 'upload' was called with POST data: " + postData); //works fine
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("You've sent: " + postData); //works ugly
response.end();
}
Let’s assume that in POST data there is a string text=123. The first line of this function outputs real data like "Request handler 'upload' was called with POST data: text=123". Although, this line response.write("You've sent: " + postData); outputs in browser next message: You've sent: undefined.
What am I doing wrong?
In your code in
server.jsthe line:Is being run first before the call in the
"end"event listener, executing the function but omitting thepostDataargument. It runs…Therefore, the response sent back to the browser is:
The
"end"event is being triggered afterwards and the event listener calls…Which correctly passes the
postDataand this gets correctly output to the console. The call toresponse.write(...)is not posted back to the browser the second time because the response at this point has ended.I hope that explains the problem.
EDIT The answer is to remove the call
The
"end"event will then be called when the client has finished posting data and you are correctly running theroutefunction at that point.