Express.js serve static folder at specific url only - node.js

I have an existing express app I'm using for an API but I also want to deliver a folder with an HTML file and some images/css/js. I can get it to serve the HTML page but it does so at / while I only want it served at /manual. Here is my stripped down code with just express.static, my / route and the catch all redirect to /
const app = express();
app.use(express.static('manual'));
app.get('/', (req, res) => {
res.status(403);
res.send('Access denied.');
return;
});
app.get('*', (req, res) => {
res.redirect(301, '/');
return;
});
What currently happens: Going to mysite.com/manual redirects to mysite.com/ which serves the index.html in the manual folder.
What I want to happen: Going to mysite.com/manual serves the index.html in the manual folder. And going to mysite.com/ throws a 403 status code.

Middleware/handlers are applied in the order you declare them, so you just need to change the order
const app = express();
app.get('/', (req, res) => {
res.status(403);
res.send('Access denied.');
return;
});
// adding a first parameter lets you apply the middleware to a route
app.use('/manual', express.static('manual'));
app.get('*', (req, res) => {
res.redirect(301, '/');
return;
});

Related

Serving Angular content and HTML+CSS content from Node/Express backend

I have one Node/Express server where I am serving both an Angular application and some static HTML. I serve the Angular application out of dist/angular and the static content out of static-content:
// This has to be in this order or else it doesnt work for some reason
app.use(express.static('./static-content'));
app.use(express.static('./dist/angular'));
app.use(parser.json());
// some other routes ...
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, '/static-content/index.html'));
});
app.get('/app/*', function (req, res) {
res.sendFile(path.join(__dirname, '/dist/angular/index.html'));
});
http.createServer(function (req, res) {
let httpsHost = req.headers.host.replace('8081', '8443');
res.writeHead(301, {"Location": "https://" + httpsHost + req.url});
res.end();
}).listen(8081);
https.createServer(httpsOptions, app).listen(8443)
If you change the order of the express.static at the top, it will not serve the static-content so I am wondering if this is the correct way to serve both an Angular application and HTML+CSS content out of one Node/Express server?

NodeJS Express middleware goes to next one without next()

I am trying to learn Express for NodeJS but I came across this:
I am trying to add 2 middlewares depeding on url, so on the /user to do something and on root to do something different. However the root middleware is always called even if i dont use next() and if i access the "/" url, the root middleware is called twice.
const express = require('express');
const app = express();
app.use('/user', (req, res, next) => {
console.log('In user middleware ');
res.send('<h1>Hello from User page</h1>');
});
app.use('/', (req, res, next) => {
console.log('In slash middleware !');
res.send('<h1>Hello from Express !</h1>');
});
app.disable('etag');
app.listen(3000);
it should be get or post not use
-get or post are routes
-use is middleware function
check this
const express = require('express');
const app = express();
app.get('/user', (req, res, next) => {
console.log('In user middleware ');
res.send('<h1>Hello from User page</h1>');
});
app.get('/', (req, res, next) => {
console.log('In slash middleware !');
res.send('<h1>Hello from Express !</h1>');
});
app.disable('etag');
app.listen(3000);
From an issue at GitHub.com
https://github.com/expressjs/express/issues/3260
Hi #davidgatti my "root path middlware" I assume you are talking about
nr_one. If so, yes, of course it is executed on every request; app.use
is a prefix-match system. Every URL starts with /, so anything mounted
at / will of course get executed :)
Okay, I can't confirm this but I suspect from the tutorial you are following you might be missing a line.
As you said, app.use is a middleware which will be added to all the route
So when you load say some url where you expect the middleware then it won't know about the request type (post, put, delete or get request).
Any alternate for this could be to try something like this
app.use('/user', (req, res, next) => {
if (req.method === 'GET') {
console.log('In user middleware ');
res.send('<h1>Hello from User page</h1>');
}
});
Again, Just check and compare his code thoroughly
Adding this link from Justin's answer for reference
In order to avoid such a problem, you have to use the return keyword.
When you send a file to the server, use return.
Try the following code,
const express = require('express');
const app = express();
app.use('/user', (req, res, next) => {
console.log('In user middleware ');
return res.send('<h1>Hello from User page</h1>');
});
app.use('/', (req, res, next) => {
console.log('In slash middleware !');
return res.send('<h1>Hello from Express !</h1>');
});
app.disable('etag');
app.listen(3000);
At line 13 and 8, I used the return keyword.
So when you make http://localhost:3000/ request, you will receive
Hello from Express !
And whenever you make http://localhost:3000/user request, you will receive
Hello from User page

Access both static content and API with Express

I have a Express REST API at /api and a frontend that I want to show at /ui. I have this:
api.js
const STATIC_FILES_PATH = path.resolve(__dirname, '..', 'frontend', 'build');
app.use(express.static(STATIC_FILES_PATH));
app.get('/ui', (_, res) => {
res.sendFile(path.resolve(STATIC_FILES_PATH, 'index.html'));
});
app.get('/api/stuff', (req, res) => {
//do stuff
});
When I navigate to /api/stuff, I still see the frontend instead of the API response. No matter the URI, it always show the frontend webpage.
What am I doing wrong?
EDIT
This is my project structure:
/api
api.js
/frontend
/build
index.html
When I navigate to /api/stuff, in my Chrome console, I see a HTTP 304! It's redirecting me to the frontend (cached) instead of showing me the JSON result (API response).
After adding this middleware:
app.get('/*', (req, res, next) => {
res.setHeader('Last-Modified', (new Date()).toUTCString());
next();
});
it's working fine. It seems Express is caching stuff. Thanks to all!
change your code with this snippet, it tested and will work correctly.
api.js
const express = require('express');
const app = express();
const path = require('path');
const STATIC_FILES_PATH = path.resolve(__dirname, 'frontend', 'build');
app.use(express.static(STATIC_FILES_PATH));
app.get('/ui', (req, res, next) => {
res.sendFile(path.resolve(STATIC_FILES_PATH, 'index.html'));
});
app.get('/api/stuff', (req, res, next) => {
res.json({title: 'staff'});
});
app.listen(3000);

Defining root and error routes in NodeJs/Express

I defined some routes for my application. Like
app.get('/page1', function (req, res) {
res.render('page1');
});
app.get('/page2', function (req, res) {
res.render('page2');
});
and if the route is missing or wrong, the application should always redirect to another page. I want to define a root route:
app.get('/', function (req, res) {
res.render('notFound'); // redirect to a 404 template
});
and what do I have to define to cover all the error or missing pages?
When having '/page1/abcdefgh' and '/fooBar' both routes should redirect to the res.render('notFound'); template.
To handle a 404 place a * route-handler below all pre-defined routes. So if none of your predefined routes will match (like /page1 or /page2), the * will get triggered.
// Will match /page1
app.get('/page1', function (req, res) {
res.render('page1');
});
// Will match /page2
app.get('/page2', function (req, res) {
res.render('page2');
});
// Will be triggered if nothing above got a match
app.get('*', function (req, res) {
res.render('notFound'); // redirect to a 404 template
});

Express.js: How to serve one file for the default "/" route, then use express.static for the rest?

I have a basic express app and I want to serve one file (after performing some logic) for the default route of /.
Unfortunately I can't use
app.use(function (res, res, next){
*logic here*
res.sendFile(filepath);
});
express.static()
because that will intercept every request and send the filepath for every request.
Is there another way of doing this?
It's enough to check the URI part of url and if it's / then send file.
Check this:
app.use(function (req, res, next) { // first must be Your middleware
if(req.path == '/') {
return res.sendFile('some file');
}
next();
});
app.use(express.static('public')); // and after it You can attach static middleware
or:
app.use(express.static('public'));
app.all('/', function (req, res) {
res.sendFile(filePath);
});
var regexp = /^\/\w+/
app.use(function (req, res, next){
if(!regexp.test(req.path)){
res.sendFile(filepath);
}
});
express.static()
this may work comment your requirement

Resources