Question

I am coming from a (traditional) server side scripting (PHP) background and am trying to experiment with Node to see what the fuss is all about.

Objective: serve up a simple web document with some style sheets and scripts on it.

My node.js script:

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

fs.readFile('index.html', function (err, html) {
    if (err) {
        throw err; 
    }       
    http.createServer(function(request, response) { 
        response.writeHeader(200, {"Content-Type": "text/html"});  
        response.write(html);  
        response.end();  
    }).listen(1337, '127.0.0.1');
});

index.html:

<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'> 
        <title>Node.js test</title>
        <link rel="stylesheet" media="screen" type="text/css" href="css/plugin.css" />
        <link rel="stylesheet" media="screen" type="text/css" href="css/xGrid.css" />
        <link rel="stylesheet" media="screen" type="text/css" href="css/jquery-ui/jquery-ui-1.10.1.custom.min.css" />
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
        <script src="js/slate.js"></script>
        <script src="js/slate.portlet.js"></script>
        <script src="js/slate.message.js"></script>
        <script src="js/plugin.js"></script>
    </head>
    <body>
        <h1 class="styled-h1">Test</h1>
    </body>
</html>

The problem I am facing:

The two script includes coming from the Google CDN are loaded on to the document fine. However, every other style sheet or script being called from my local file system get interpreted as text/html and so don't have the intended effect. Here is a screenshot from Google Chrome console:

enter image description here

I want to understand why this is happening.

PS: I know I can use a framework like Express to make things easier but I want to get a hold of the fundamentals first.

Was it helpful?

Solution

Simple: you're setting the Content-Type header to text/html, always. Also, it will always serve your index.html file. Look:

fs.readFile('index.html', function (err, html) {
    if (err) {
        throw err; 
    }       
    http.createServer(function(request, response) { 
        response.writeHeader(200, {"Content-Type": "text/html"});  // <-- HERE!
        response.write(html);  // <-- HERE!
        response.end();  
    }).listen(1337, '127.0.0.1');
});

You should parse the URL, look up what file you want to require, read its contents and write them to the response if it exists, otherwise serve an 404 error. Also, you'll need to set the correct headers.

So, do you still want to do it at your own?
At least, try something like send, which is a basic static file server.

OTHER TIPS

Rather than pointing contentType to text/html, You can do some thing like this using path module

var filePath = req.url;
if (filePath == '/')
  filePath = '/index.html';

filePath = __dirname+filePath;
var extname = path.extname(filePath);
var contentType = 'text/html';

switch (extname) {
    case '.js':
        contentType = 'text/javascript';
        break;
    case '.css':
        contentType = 'text/css';
        break;
}


fs.exists(filePath, function(exists) {

    if (exists) {
        fs.readFile(filePath, function(error, content) {
            if (error) {
                res.writeHead(500);
                res.end();
            }
            else {                   
                res.writeHead(200, { 'Content-Type': contentType });
                res.end(content, 'utf-8');                  
            }
        });
    }

You are creating a web server that does one thing and one thing only irrespective of what path or parameters are sent: it serves your HTML file index.html with MIME type text/html.

The requests for CSS files are relative path requests, i.e. when the web browser sees the instruction to load css/plugin.css it calls your web server with a new path; but your web server ignores the path and just returns index.html again with MIME type text/html. Your web browser throws errors about the wrong MIME type but what it didn't tell you was that you just loaded index.html again.

To confirm for yourself click on the following link: http://127.0.0.1:1337/css/plugin.css

Your server is responding to all request with a unique response... When the browser request for CSS and Scripts, your server do the only thing he knows !!!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top