Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js with fs.readFile not able to render file content via http

Tags:

node.js

I'm learning node.js but am struggling with the fs.readFile function in my simple web server code (demo.js below). If I access http://localhost:8001/demo.html I get no data back in the browser, but if I access '/' or any other file name I see the "hello world' or 404 pages as expected.

I have included the content of demo.html and the node console output where the log messages suggest that the readFile is reading the file OK, but I get nothing in the browser and don't see the 'Got here D' log message.

I'm sure I must be missing something obvious but can't see what. Any help would be appreciated!

demo.js code:

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>

node console output:

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
like image 583
Bruce Alport Avatar asked May 15 '14 13:05

Bruce Alport


1 Answers

The problem lies in the position of the response.end() call.

fs.readFile is an asynchronous function; like all functions in node related to I/O. This means that the reading of the file is done in a background process and when the data is available your defined callback function is called with the result.

Node continues to execute your code after fs.readFile, which results in response.end() being called before your callback function builds the response.

To fix this you have to move the response.end() call into the cases like this:

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;
    }
});
like image 165
Sascha Wolf Avatar answered Oct 14 '22 08:10

Sascha Wolf