Can't load local files when using NodeJS server - node.js

I'm very new to NodeJS, and I'm currently playing around with it (and websockets), so this question might be a bit dumb. Anyway, I'm following a tutorial which has given me a simple app.js containing the following:
var fs = require('fs')
, http = require('http')
, socketio = require('socket.io');
var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-type': 'text/html'});
res.end(fs.readFileSync(__dirname + '/index.html'));
}).listen(8080, function() {
console.log('Listening at: http://localhost:8080');
});
socketio.listen(server).on('connection', function (socket) {
socket.on('message', function (msg) {
console.log('Message Received: ', msg);
socket.broadcast.emit('message', msg);
});
});
In my index.html I'm trying to load some js and css files, but I can't seem to load them. The files are inside a js folder which is in the same directory as my app.js and index.html, and I'm trying to load them like so:
<script src="/js/script.js"></script>
If I look at the response from the request in my browser, it's returning the content of index.html.
Again, sorry if this question is silly, but I'm stuck and have no clue where to look.
Thanks!

A web server in node.js does not serve ANY files by default (unlike some other web servers). So, if you want js files to be served, you have to define a web server route that will serve them. The code you show returns index.html for all incoming requests coming into that http server so, it should be no surpise that when a request comes in for /js/script.js, your web server sends out index.html.
A typical framework to use with node.js for web serving is Express and it has express.static() that can be used to define a route that will cover all your static files or all files in a particular directory. You could, of course, code your own static file handling or find some other module to do that also. The point is that you have to write or configure some code to serve your static resource files. That is not done for you automatically by the node.js http server.

you can specify to the server in which folder to look for what
for static files such as css, images you can use
public directory, you can provide your custom directory, but it's better to use public ,same goes for views
always require
const PATH = require('path')
app.use(express.static(PATH.join(__dirname, 'public')));
for template files such as .ejs, .html, .jade use
app.set('views', PATH.join(__dirname, 'views'));

Related

Why is node.js sending the entire public folder, When only root index.html specified?

So I am making a node.js server for my webpage. And after having added root route that sends the index.html it also sends the game.html page with out it being specified. The game.html file is in a folder called game in the root directory. So I am wondering why is it sending the game.html file? And is it supposed to happened, with out me saying what the server is supposed to send in the "/game" path?
I am using Node.js and Express.
const express = require("express");
const app = express();
const port = 3000;
app.use(express.static("public"));
// ROUTES
app.get("/", (req, res) => {
res.sendFile("index.html", {root: "public"});
})
// Listening
app.listen(port, () => {
console.log(`Listening at port http://localhost:${port}`);
})
In your code, you have two route handlers that can send responses back to incoming requests.
This one:
app.get("/", (req, res) => {
res.sendFile("index.html", {root: "public"});
});
is pretty obvious. If the request is /, then send back the index.html file.
This one:
app.use(express.static("public"));
tells express to compare the incoming path of the request to any files in your public directory and, if they match, then send that file back as the response to that request. This is exactly what express.static() is designed for and what it is supposed to do. It is commonly used for serving static resources such as CSS files, JS files and even static HTML files since one route can automatically serve an entire directory hierarchy.
So, if an incoming request arrives for /game/game.html and, the public directory contains this:
public
game
game.html
Then, express.static("public") will find a match for /game/game.html and will send back the game.html file as the response. This is working as designed.
Because of this, you should never put anything that you don't want automatically served inside the directory that you pass to express.static() - in your specific code example, the "public" directory.

Using Mixpanel - Node Library in Express

I am currently trying integrate the Mixpanel Node library into a test application that I am building. This is a Node.js application using the express framework.
As per the express docs, I have a JS file to manage the project, a folder called "public" that contains all of my static files, and another folder with the node modules that come with express.
I have two static HTML pages in "public" that I am trying to put mixpanel tracking into. I am running the project locally by running node app.js.
app.js includes:
const express = require('express');
const app = express();
const port = 3000;
const path = require('path');
//Mixpanel Additions
var Mixpanel = require('mixpanel');
var mixpanel = Mixpanel.init('<I am putting my project token here>', {
protocol: 'https'
});
//App Configuration and Init
app.use(express.static('public'));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname + '/public/page.html'));
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
In my HTML files I try to use mixpanel functions by putting them into script tags:
<script>
mixpanel.track("event")
</script>
But when I run node app.js and view the page in my browser it says:
Uncaught ReferenceError: mixpanel is not defined
I have a pretty poor understanding of node.js, but I am imagining that I need to use app.use(), app.get(), or something along those lines to get the Mixpanel lib loaded into the app. What am I doing wrong? I also realize that my understanding of Express and Node is pretty rudimentary, so any additional knowledge is appreciated, especially if I am way off.
If you want to call mixpanel tracking functions in the browser, you should load the mixpanel library in a script tag on the browser side, as seen here:
https://developer.mixpanel.com/docs/javascript
The purpose of the node.js package is to send events from the server side, like if you wanted to log when page.html is rendered, you could do
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname + '/public/page.html'));
mixpanel.track('event')
});

How to create a node based server to serve REST API and also deploy the application.

I am new to nodeJS server area, need help in understanding how to work with REST API (using express) and deploy the angular application over a singe node server and same ports.
By deploying i want to understand if user hit below url http://localhost:8000/<page_name> then the specified page should open.
And is user hit below url using get or post request
http://localhost:8000/api/<api_name> then a json or a text will be returned.
How to run both the thing over a single node server.
Lets assume, you have all your static files in the /public folder of you app. Generally spoken, if you are using express.static, you should also get your index.html because this is handled by default for each directory.
In your case, as you are using Angular, the routing is handled from the client side (SPA). You should only have one single index.html after building your Angular app. All files from your dist folder should then be placed into your /public folder. Then you need to make sure, that initial file serving provides your index.html like so:
In this example static files are served first, then your API and if nothing is found, you are getting back you index file.
const express = require('express');
const app = express();
// serve static files
app.static(__dirname + '/public'));
// serve your API
app.get('/api/welcome', function (req, res) {
res.send('Welcome');
});
// fallback routing (server side handling)
app.get(/.*/, function (req, res) {
res.sendFile(__dirname + ‘/public/index.html‘
});
app.listen(3000);
Next time please make sure, to give all necessary information in your question ;-)
With the help from Sebastian, so far I can find a solution but its not working when i am hitting URL for different pages.
const express = require('express');
const app = express();
app.use(express.static('public'))
Please provide your suggestions.

Reaching html file in another subfolder express.js

My folder hierarchy is as follows;
public
----index.html
src
----server.js
when I run the code
var express = require('express');
var app = express();
var serv = require('http').Server(app);
var net = require('net');
var path = require('path');
var port = 3000;
app.use('/../public/', express.static(path.join(__dirname + '/../public/')));
app.get('/', function(req,res){
res.sendFile(__dirname + '/../public/index.html');
});
serv.listen(3000, function(){
console.log('port ' + port + ' is started to being listened')
});
var io = require('socket.io')(serv,{});
it returns forbidden error. How can I reach a file in another subfile?
First of all, what I thought solved it actually didn't solve because I am running multiple projects to understand the basics and I was confused. But now everything is clear. What I am actually trying to do is trying to use express to divide everything to folders. As I didn't know much about http, I watched a lot of videos and finally, I figured it out after watching official introduction video of express on youtube.
Here again what I am trying to accomplish;
-localhost
--public
---index.html
--src
---all server js files and other files that will concern game programming.
As I was trying to reach above, I couldn't manage to do it. What did actually do the trick is;
creating a variable that specifies 'public' directory which is another sub directory under localhost and use it as static which was simple from the beginning but as I didn't know much, I wasn't able to use it after studying few tutorials. As Michael mentioned above, I didn't even need following lines;
app.get(publicDir, function(req, res){
res.sendFile('index.html');
})
All I did was;
var publicDir = require('path').join(__dirname, '/../public');
app.use(express.static(publicDir));
app.use('/../public/'
doesn't really make sense. This parameter is representing the request URL. You can't listen for request URL's which are in the hierarchy somewhere else but not inside your root folder.
Remember that app.use('/' equals a request URL like http://localhost:3000 - meaning this is the absolute basis of the website - the so called root. So where should '/../public' point to? There is no URL with which you could reach such an address.
If you write app.use('/public' it will listen for requests on http://localhost:3000/public
But of course you can send files located in a file structure like you have. So probably what you wanted is:
app.use(express.static(__dirname + '/../public'));
in order to search the static files in a folder structure like:
public
-styles.css
-script.js
-index.html
server
-currentscript.js
where you could access static files like http://localhost:3000/styles.css
You can also completely remove this controller:
app.get('/', function(req,res){
res.sendFile(__dirname + '/../public/index.html');
});
static files like HTML are already served by the Express static files controller mentioned above.
This is enough to access your index.html by calling http://localhost:3000

Express js routing is downloading file and not rendering it

I am trying to implement a router on the server side with node.js and express.js.
I want to serve a file statically, but I already got this to work for a index.html file I created. No problems there.
My setup has tons of fileName.csp files (i.e. they end in .csp). Anyways, when I try to access a .csp file in the browser (inside it is really just a .html page - but the server side language must have it as a .csp file extension) but when I try to access it, the browser (google chrome) downloads the .csp file instead of rendering it!
I could really use some help since I'm new to all of this.
the line of code that is allowing the download of the .csp file, the code that exposes the directory where the .csp files live, is
app.use('/static', express.static('D:/CACHESYS/CSP/cah/'));
below is pretty much the whole snippet of code
var http = require('http');
var express = require('express');
var app = express();
app.use('/static', express.static('D:/CACHESYS/CSP/cah/'));
app.listen(3000, function() {
console.log('listening on port 3000');
})
app.get('/home', function(request, response) {
response.end('going to /home');
})
app.get('/csp/cah/MARS.csp', function(request, response) {
response.end('Trying to navigate to /csp/cah/MARS.csp');
})
p.s. the actual file path that is being downloaded is
D:/CACHESYS/CSP/cah/fileName.csp
just to give some more context for the question.
any help is appreciated
thanks!
You need to tell express what content type a .csp file is. You can do this with the following line:
express.static.mime.define({
'text/html': ['csp']
});
Although, if the file is an HTML file, it should probably have the .html extension. Also, if you are simply serving static files it is good practice to use an HTTP server like nginx or Apache to do that, rather than Node.js.
The reason this works is express will set the header Content-Type: text/html. This tells the browser it is HTML and it should render it as such. By default if a browser comes across a content type it doesn't recognise, it simply downloads it.

Resources