Reputation: 482
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
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
Reputation: 71
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"
Always to use express.static to serve static files
Upvotes: 4