node.js中的奇怪行为

时间:2012-09-07 22:07:06

标签: node.js

我正在阅读http://www.nodebeginner.org中的教程,我在数据输出中有一个奇怪的行为。我知道,Stackoverflow上有类似的问题,但没有答案。所以我有这个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

调用requestHandler.upload的router.js代码 - 我的错误函数

//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()
    }
}

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();
}

我们假设在POST数据中有一个字符串text=123。该函数的第一行输出真实数据,如"Request handler 'upload' was called with POST data: text=123"。虽然,此行response.write("You've sent: " + postData);会在浏览器中输出下一条消息:You've sent: undefined。 我做错了什么?

1 个答案:

答案 0 :(得分:3)

server.js行的代码中:

var content = route(handle, pathname, response)

"end"事件侦听器中调用之前首先运行,执行该函数但省略postData参数。它运行...

response.write("You've sent: " + postData);
response.end();

因此,发送回浏览器的响应是:

You've sent: undefined

之后触发"end"事件,事件监听器调用...

route(handle, pathname, response, postData)

正确传递postData并将其正确输出到控制台。对response.write(...)的调用不会第二次发回浏览器,因为此时的响应已经结束。

我希望能解释这个问题。

编辑答案是删除电话

var content = route(handle, pathname, response)

当客户端完成发布数据并且您在此时正确运行"end"函数时,将调用route事件。