具有fs.readFile的Node.js无法通过http呈现文件内容

时间:2014-05-15 13:45:21

标签: node.js

我正在学习node.js,但我在简单的Web服务器代码(下面的demo.js)中遇到了fs.readFile函数。如果我访问http://localhost:8001/demo.html我在浏览器中没有收到任何数据,但是如果我访问' /'或任何其他文件名我看到"你好世界'或预期的404页。

我已经包含了demo.html和节点控制台输出的内容,其中日志消息表明readFile正在读取文件,但我在浏览器中什么都没有,并且没有看到'到了D'日志消息。

我确定我必须遗漏一些显而易见但却看不清楚的东西。任何帮助将不胜感激!

demo.js代码:

var http = require("http");
var url = require('url');
var fs = require('fs');

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 '/demo.html':
            fs.readFile(__dirname + path, function(error,data){
                console.log("error: " + error);
                console.log("data: " + data);
                if (error){
                    console.log("Got here A");
                    response.writeHead(404);
                    response.write("oops problem loading this page - 404");
                }   
                else{
                    console.log("Got here B");
                    response.writeHead(200, {"Content-Type": "text/html"});
                    response.write(data);
                }
            });
            break;
        default:
            console.log("Got here C");
            response.writeHead(404);
            response.write("oops this page doesn't exist - 404");
            break;
    }
    response.end();
    console.log("Got here D");
});

server.listen(8001);

demo.html:

<html>
<body>This is my demo page</body>
</html>

节点控制台输出:

C:\code\Node>node demo.js
Connection
Got here D
error: null
data: <html>
<body>This is my demo page</body>
</html>

Got here B

1 个答案:

答案 0 :(得分:9)

问题在于response.end()电话的位置。

fs.readFile是一个异步函数;与节点中与 I / O 相关的所有函数一样。这意味着文件的读取是在后台过程中完成的,当数据可用时,将使用结果调用已定义的回调函数。

节点继续在fs.readFile之后执行您的代码,这会导致在您的回调函数构建响应之前调用response.end()

要解决此问题,您必须将response.end()调用移至以下情况:

var http = require("http");
var url = require('url');
var fs = require('fs');

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');
            response.end();
            break;
        case '/demo.html':
            fs.readFile(__dirname + path, function(error,data){
                console.log("error: " + error);
                console.log("data: " + data);
                if (error){
                    response.writeHead(404);
                    response.write("oops problem loading this page - 404");
                }
                else{
                    response.writeHead(200, {"Content-Type": "text/html"});
                    response.write(data);
                }

                response.end();
            });
            break;
        default:
            response.writeHead(404);
            response.write("oops this page doesn't exist - 404");
            response.end();
            break;
    }
});