0

我是一个完整的节点新手,我遇到了一个问题:

var http    = require("http");
var url     = require('url');
var fs      = require('fs');
var io      = require('socket.io');

var server = http.createServer(function(request, response){ 
console.log('Connection');
var path = url.parse(request.url).pathname;

switch(path){
    case '/':
        response.writeHead(200, {'Content-Type': 'text/html'}); 
        response.write('Hello World');
        break;
    case '/socket.html':
        fs.readFile(__dirname + path, function(error, data){
            if (error){
                response.writeHead(404);
                response.write("This doesn't exist - 404");
                console.log(error);
            } else {
                console.log('hi!'); // **************<---- I'm getting here
                response.writeHead(404, {'Content-Type': 'text/html'});
                response.write(data, 'utf8');
            }
        });
        break;
    default:
        response.writeHead(404);
        response.write("This page does not exist - 404");
        console.log(path);
        break;
}
response.end(); 
}); 

server.listen(8001);

io.listen(server);

我正在进入'else'中的console.log(),但response.write根本不输出任何东西,如果我console.log(data)我得到

4

2 回答 2

1

您应该在写入后调用 .end 。

response.writeHead(404, {'Content-Type': 'text/html'});
response.write(data, 'utf8');
response.end();

http://nodejs.org/api/http.html#http_response_end_data_encoding

于 2013-10-08T09:48:46.563 回答
1

从我的评论延伸:

fs.readFile()是一个异步调用,这意味着它会简单地告诉 Node 尝试打开文件,然后继续而不等待它。所以通过这段代码:

fs.readFile(__dirname + path, function(error, data){
    if (error){
        response.writeHead(404);
        response.write("This doesn't exist - 404");
        console.log(error);
    } else {
        console.log('hi!'); // **************<---- I'm getting here
        response.writeHead(404, {'Content-Type': 'text/html'});
        response.write(data, 'utf8');
    }
});
response.end();

这段代码的作用是:

  1. 你:“嘿节点,帮我打开这个文件;完成后告诉我”;
  2. 你:“结束回复,我不再需要那个了。”;
  3. (时间不详
    ) 节点:“嗨,文件准备好了。”。
    你:“酷,现在将文件写入响应流。”
    节点:“...... WTF伙计,你已经关闭了流!”

(好的,我添加了最后一行)

因此,要按照您的意愿行事,您有​​两种选择:

  1. 使用 同步文件打开操作fs.readFileSync(),这样你就可以做你熟悉的“线性”编程:

    try {
        var data=fs.readFileSync(__dirname+path,{"encoding":"utf8"});
        response.writeHead(200,{"Content-Type":"text/html"});
        response.write(data,"utf8");
    }catch(e){
        response.writeHead(400,{"Content-Type":"text/plain"});
        response.write("This doesn't exist -  404");
    }
    response.end();
    
  2. 在 的回调函数中结束响应fs.readFile(),而不是在服务器监听器中:

    switch(path){
        case '/':
            response.writeHead(200, {'Content-Type': 'text/html'}); 
            response.write('Hello World');
            response.end();/* here */
            break;
        case '/socket.html':
            fs.readFile(__dirname + path, function(error, data){
                if (error){
                    response.writeHead(404);
                    response.write("This doesn't exist - 404");
                    response.end(); /* here */
                    console.log(error);
                } else {
                    console.log('hi!');
                    response.writeHead(200, {'Content-Type': 'text/html'});
                    response.write(data, 'utf8');
                    response.end(); /* here */
                }
            });
            break;
        default:
            response.writeHead(404);
            response.write("This page does not exist - 404");
            response.end(); /* here */
            console.log(path);
            break;
    }
    //response.end(); <-- get rid of this line
    

另请注意,当文件打开成功时,我在调用中更改404200writeHead(),我想这就是您的实际意思。

于 2013-10-09T03:24:37.880 回答