node express cannot GET static content - node.js

Im running a node app inside of /opt/myapp directory.
I have haproxy in front content switching on path_beg /myapp
backend server is listening on port 3000
directory structure:
/opt/myapp
index.js
package, modules
static
public
myfile.html
const express = require("express");
const path = require('path');
const app = express();
app.listen(3000, () => console.log("listening on 3000 "+__dirname+" "+process.cwd()));
app.use(express.static(__dirname+'/static/public')); //nope
//app.use(express.static('..'+'/static/public')); //nope
//app.use(express.static(path.join(__dirname, '/static/public/'))); //nope
Where __dirname outputs /opt/myapp and process.cwd() outputs /opt/myapp
I tried both concantenation and path.join with same results. Cannot GET myfile.html
curl directly on the server to http://host.com:3000 does work by returning the page,
but from browser (in front of haproxy), http://host.com/myapp/myfile.html does not work.
I suppose that I can remove the /myapp from the path in haproxy on the backend, but is there a way with express that i can account for the base directory?

This worked:
app.use('/myapp/',express.static('static/public'));

Related

Node Express - requesting any file returns 404 not found

I have deployed an AWS LightSail Node server with Express on it.
Starting the app on port 3000 correctly activates app.js and display in the browser the projected string (http://my.ip.address:3000):
Welcome to the Whiteboard server! this is the home page on port 3000 with base dir: /opt/bitnami/apache/htdocs/whiteboard
This is the app.js:
const express = require("express");
const app = express();
const port = 3000;
global.__basedir = __dirname;
app.use(express.json());
app.listen(port, () => {
console.log(`Whiteboard listening on port: ${port}`);
});
app.get("/", (req, res) => {
res.send(`Welcome to the Whiteboard server! this is the home page on port ${port} with base dir: ${__basedir}`);
});
However, Trying to request any file residing in the root folder (...apache/htdocs/whiteboard) such as:
http://my.ip.address:3000/Jeanette_Blog1.png
http://my.ip.address:3000/index.html
Always returns this message in the browser:
Cannot GET /Jeanette_Blog1.png
Shows as 404 error in the console.
Btw, although the path shows apache, I have actually installed node with needed modules and express - as can be seen in the app.js file up here. The apache is just part of the node image AWS LightSail creates through their partner Bitnami.
What am I missing?
An express server by itself does not serve any files by default. If you want to serve a directory or a directory hierarchy of static files, you have to use express.static() (or something similar) in a route definition.
You should not configure express.static() to point at the same directory that contains your server code because that would enable people to look at your server files. It is a popular convention to make a sub-directory (often called "/public", either below or at the same level as your server files. Here's an example with express.static() configured for a directory at the same level. You would add this line:
app.use(express.static(path.join(__dirname, "../public")));
And, it would all look like this:
const express = require("express");
const app = express();
const path = require('path');
const port = 3000;
global.__basedir = __dirname;
// serve public files
app.use(express.static(path.join(__dirname, "../public")), {index: false});
app.use(express.json());
app.listen(port, () => {
console.log(`Whiteboard listening on port: ${port}`);
});
app.get("/", (req, res) => {
res.send(`Welcome to the Whiteboard server! this is the home page on port ${port} with base dir: ${__basedir}`);
});
Then, you would move your static files such as index.html and Jeanette_Blog1.png to that /public directory. They can be referred to from the browser as URLS such as /index.html and /Jeanette_Blog1.png. The express.static() middleware will check the incoming path to see if it matches a filename in the /public directory and, if so, it will serve it. If it doesn't match a file, then it will continue routing to other route handlers you have defined.

Express server and NGINX proxy only serving index.html, no other files

I have a very simple express app which serves everything in the build folder for my react app. Here's the entire thing:
const express = require("express");
require("dotenv").config();
const app = express();
const port = process.env.PORT || 5000;
app.use(express.static(process.env.PUBLIC_DIR));
app.use(express.json());
app.listen(port, () => {
console.log(`Server is running on port ${port}...`);
});
When running this on my local machine, it works fine. No issues.
On my EC2 instance, I'm using NGINX as a reverse proxy. Here's what the config in my default sites-available file looks like:
location / {
proxy_pass http://localhost:5000/;
}
location /upvotes {
proxy_pass http://localhost:5002/;
}
When you just go to the main site, another express app on 5000 serves a totally unrelated Gatsby project. That works fine, no issues.
When you go to /upvotes, this express app on 5002 does serve the index.html file perfectly fine, but it doesn't serve any of the accompanying .js and .css files that are also in that directory.
Does anyone know why this could be happening?
I eventually gave up and combined the two express apps into one and handled the /upvotes route using express. 🤷

How does express know this routing?

I create a simple express server and serve the static files
const express = require('express');
const app = express();
app.use(express.static('public'));
app.listen(3000, () => {
console.log('Listening on port 3000')
})
When I head to localhost:3000, the index.html in my public directory renders for the route ' / '. I didn't explicitly write the route in my index.js file. How does express know this?
I've tried changing the file name from index.html to random.html and I get an error. CANNOT GET /
As mentioned in the comments, app.use(express.static('public')) is responsible for this. This will essentially serve all files in the public folder you have in the project. If you have an index.html in the public folder, then that will be served at the / endpoint automatically. This is a convention that most websites follow, and is documented in this SO post.
Here is the relevant documentation on express.static(...): https://expressjs.com/en/starter/static-files.html

Upload react basic application to server

I am trying to upload the following to my personal server to see how it works:
https://github.com/remarkablemark/universal-react-tutorial
I have tried to change the port here: (server.js)
require('babel-register')({
presets: ['react']
});
var express = require('express');
var app = express();
app.use(express.static('public'));
app.use(require('./routes/index.jsx'));
var PORT = 80;
app.listen(PORT, function() {
console.log('http://localhost:' + PORT);
});
but when I type the corresponding url I get this:
**
Index of /ReactServer
Parent Directory
Component.jsx
client.js
public/
routes/
server.js
webpack.config.js
Apache Server at www.alessandrosantese.com Port 80
**
I can see the app working fine at http://localhost:3000/ but I would like to test it on the server (I have never deployed a react application on a live server)
This is more of deploying node.js to remote server.
I would recommend you to use heroku
Follow these steps to deploy your app easily to their servers.

Node.js and Express: "Cannot GET /" static site

I'm working on a small Node app and things were working fine. It needs to serve some static files from a directory /source.
Today, after a computer restart, when I visit my local site all I get is Cannot GET /. Nothing in the Node config has changed since it was working last.
var express = require('express'),
app = express(),
path = require('path'),
fs = require('fs');
// Load our static site to start with
app.use(express.static(path.join(__dirname, 'source')));
// Start the node server
app.listen(3000, function() {
var host = this.address().address,
port = this.address().port;
console.log('Serving Atenium at http://%s:%s', host, port);
});
My folders look like:
|- app/
|-- index.js
|- source/
|-- <static files>
Any ideas as to why this just stopped working?
Could you have updated your express module in the process? I believe in Express 4, static content is now handled by the serve-static middleware library found here https://github.com/expressjs/serve-static .
Instead of using
app.use(express.static(path.join(__dirname, 'source')));
you have to create a virtual static path like:
app.use('/source', express.static(path.join(__dirname, 'source')));

Resources