edddd
edddd

Reputation: 482

CSS and JS not loading with trailing slash in URL

I was building a Node.js server locally that would listen at localhost:8080. The landing page is an html file named index.html. If I type localhost:8080/index.html, the HTML, along with the CSS file (main.css) and JavaScript (main.js) located in the same folder as index.html will load just fine. But if I typed the same URL with a trailing slash, as localhost:8080/index.html/, it only loads the html, not the CSS or JS. I tried going into the HTML page source in Chrome and clicking on the css file in there, and it seems to look for a localhost:8080/index.html/main.css file (as seen from the address bar of the browser), which obviously doesn't exist. It appears that it's assuming index.html to be a directory for some reason. Any help would be great.

Edit: The part of the server that deals with routing looks like this (I'm just starting out, and I'm trying to route without using Express.js):

const http = require("http");
const fs = require("fs");
const path = require("path");
const url = require("url");

http.createServer(function(request, response) {
    function writeContentType(headerText) {
        response.setHeader("Content-Type", headerText);
    }
    let requestedPath = url.parse(request.url, true).pathname;
    requestedPath = requestedPath.replace(/^\/+|\/+$/g, "");
    requestedPath = requestedPath.replace(/\//g, "\\");
    requestedPath = "\\" + requestedPath;
    if (requestedPath === "\\") requestedPath = "\\index.html";
    if (!fs.existsSync(__dirname + requestedPath)) {
        console.log("file does not exist, requested path is " + __dirname + requestedPath);
        writeContentType("text/html");
        response.write("<h1>Error 404</h1><h2>Page not found</h2>");
        response.end();
    } else {
        let responseFile = fs.readFileSync(__dirname + requestedPath, function(err) {
            console.log(err);
        });
        if (responseFile) {
            let fileExtension = path.extname(requestedPath);
            switch(fileExtension) {
                case ".html" : writeContentType("text/html"); break;
                case ".css" : writeContentType("text/css"); break;
                case ".js" : writeContentType("text/javascript"); break;
                case ".svg" : writeContentType("image/svg+xml"); break;
                case ".jpg" :
                case ".jpeg" : writeContentType("image/jpeg"); break;
            }
            response.end(responseFile);
        }
    }
}).listen(8080);

The idea was to strip all slashes at the beginning and end of requestedPath, replace any slashes on the inside with backslashes because my filesystem is in windows, and then add a backslash at the beginning, and then look for the file in the filesystem. I might be going against a lot of best practices here, I'm just starting out.

Upvotes: 1

Views: 1968

Answers (2)

indyanin
indyanin

Reputation: 852

This is expected behavior, when you hit localhost:8080/ you expect to be served with index.html

So when you add trailing slash it assumes it is a directory and looks for your files there.

Try to use npm package express-slash or make custom middleware such as:

app.use(function(req, res, next) {
    if (req.path.substr(-1) == '/' && req.path.length > 1) {
       const query = req.url.slice(req.path.length);
       res.redirect(301, req.path.slice(0, -1) + query);
    } else {
       next();
    }
});

A similar problem can be found here

Upvotes: 1

Mudit Bhadouria
Mudit Bhadouria

Reputation: 71

  1. Wherever you referring the JS and CSS files, use a '/' in front so that it always takes searches in root directory for the files. For example,

    href="/styles.css"

  2. Always to use express.static to serve static files

Upvotes: 4

Related Questions