So I'm learning node.js and I can successfully have it route to a new HTML page and display basic text. However, when I try to add any other javascripts, CSS, or even images, it appearently treats them like its loading a whole HTML file.
The code would be too long to really post so I'll share my console.log output:
- request for /start received.
- About to route a request for /start
- Request handler "start" was called.
- request for /socket.io/lib/socket.io.js received.
- About to route a request for /socket.io/lib/socket.io.js
- No request handler found for /socket.io/lib/socket.io.js
- request for /style.css received.
- About to route a request for /style.css
- No request handler found for /style.css
- request for /test.jpg received.
- About to route a request for /test.jpg
- No request handler found for /test.jpg
- request for /favicon.ico received.
- About to route a request for /favicon.ico
- No request handler found for /favicon.ico
I understand the whole favicon.ico mess but I dont know why it treats the other files the way it does.
What do I need to do/consider when loading pages with Node.js?
You have to remember that node.js isn't a web server which serves files in a webroot directory by default. It is a low level application which has an API to serve network and http requests. While express.js exposes a public folder where you can put your resources, it fetches the files and replies to the requests using roughly the same approach you have mentioned.
Node.js isn't exactly optimized to handle serve files on HTTP. What most people do on production is install a reverse proxy (nginx is a popular choice) so route requests. You can instruct nginx to simply serve the file if found in the web root, otherwise redirect requests to node.js.
Well, for those who are rather uninitiated as I am, here is one way to display most common file types without using Express.
var file_path = "";
var mimes = {
'css': 'text/css',
'js': 'text/javascript',
'htm': 'text/html',
'html': 'text/html',
'png': 'image/png',
'jpg': 'image/jpg',
'jpeg': 'image/jpeg'
};
// parses the url request for a file and pulls the pathname
var url_request = url.parse(request.url).pathname;
// finds the placement of '.' to determine the extension
var tmp = url_request.lastIndexOf(".");
// determines the extension by uing .substring that takes everything after '.'
var extension = url_request.substring((tmp + 1));
//set path of static pages
if (extension === 'css' || extension === 'js' || extension === 'htm' || extension === 'html' || extension === 'png' || extension === 'jpg' || extension === 'jpeg'){
file_path = url_request.replace("/", "");
}
//load needed pages and static files
fs.readFile(file_path, function (error, data){
if(error){
response.writeHeader(500, {"Content-Type": "text/html"});
response.write("<h1>FS READ FILE ERROR: Internal Server Error!</h1>");
}
else{
response.writeHeader(200, {"Content-Type": mimes[extension]});
response.write(data);
}
response.end();
});
I would love to know of a more succinct way of doing this without using Express.