Markus Appel
Markus Appel

Reputation: 3238

Node.js blocking Bootstrap?

I am fairly new to Node.js and JavaScript in general, but I want to build a website using as little overhead as possible.

I want to achieve this with Node.js and Bootstrap.

This is my server.js file:

var http = require('http');
var fs = require("fs");
 
http.createServer(
    //This function decides which content type to use for which type of request.
    //This is also used to restrict the type of files that a user is allowed to request.
    function(request, response) {

        //For debugging
        console.log(request.connection.remoteAddress.toString() + " requested the url " + request.url.toString());

        if(/^\/[a-zA-Z0-9\/]*.css$/.test(request.url.toString())){
            //Send the requested file if it end with .css
            sendFileContent(request, response, request.url.toString().substring(1), "text/css");
        }
        else if(/^\/[a-zA-Z0-9\/]*.js$/.test(request.url.toString())){
            //Send the requested file if it end with .js
            sendFileContent(request, response, request.url.toString().substring(1), "text/javascript");
        }
        else {
            //Answer any other request with the index.html file, because this is a single page application.
            sendFileContent(request, response, "index.html", "text/html");
        }
    }
).listen(80);
  
function sendFileContent(request, response, fileName, contentType){
    fs.readFile(fileName, function(err, data){
        if(err){
            response.writeHead(404);
            //TODO: Better 404 page!
            response.write("Not Found!");
            console.log(request.connection.remoteAddress.toString() + " received a 404 error");
        }
        else{
            response.writeHead(200, {'Content-Type': contentType});
            response.write(data);
        }
        response.end();
    });
}

It works well. If I add a script to the html document and, for example, use document.write() in it, it appears on the page. Now for Bootstrap, I saw that you would only need four files, usually provided via CDN or with a tool like webpack or bower. So I just downloaded the four files bootstrap.min.js, bootstrap.min.css, jquery.min.js and popper.js and put them in a scripts folder next to the rest of the files. Of course, I use a relative path like scripts/bootstrap/js/bootstrap.min.js instead of the CDN link.

When running the Node.js Server, I can see that the files get requested and sent over successfully, but somehow the bootstrap look does not appear (But everything is visible).

Here is the HTML document (index.html) I am using:

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Index</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <link rel="stylesheet" href="scripts/bootstrap/css/bootstrap.min.css">
    </head>
    <body>

        <div class="alert alert-primary" role="alert">
            This is an alert!
        </div>

        <script type="text/javascript" src="scripts/jquery/jquery.min.js"></script>
        <script type="text/javascript" src="scripts/popper/popper.js"></script>
        <script type="text/javascript" src="scripts/bootstrap/js/bootstrap.min.js"></script>

    </body>
</html>

And now, here's the weird part: Opening the index.html file manually results in correct display of all bootstrap elements. This is why I concluded it has something to do with Node.js.

Does anyone know how to fix this?

Upvotes: 0

Views: 299

Answers (1)

James Thorpe
James Thorpe

Reputation: 32212

Your regex doesn't match your CSS filename, so it's serving up index.html instead of the actual CSS.

Because you're using the .min.css file, you need to look for . in the filename, other than before the extension:

if(/^\/[a-zA-Z0-9\/.]*.css$/.test(request.url.toString())){
//                 ^

The same applies to your JavaScript one too.

Upvotes: 1

Related Questions