Having a middleware function before express.static doesnt work - node.js

I am running the latest express (4.1.1 as of writing). It has this middleware included to serve static files.
So the usual code to include this middleware is:
app.use(express.static(path.join(__dirname, 'public')));
And great that all works fine. But if I try to include a middleware before that, eg:
app.use(function(req,res,next){
next();
}, express.static(path.join(__dirname, 'public')));
The serve-static middleware now gives me 404s.
I am not sure why this is happening. Did I implement the middleware that goes before the static middleware incorrectly?

Your use of app.use() is incorrect. From the documentation:
app.use([path], function)
Use the given middleware function, with optional mount path, defaulting to "/".
You will notice that app.use accepts an optional path and a function, not multiple functions. Therefore, you should be defining each middleware with its own app.use call, as seen below:
app.use(function(req,res,next){
next();
});
app.use(express.static(path.join(__dirname, 'public')));

Related

How can I configure express to serve a single home page for many different paths?

This is what I have in mind:
app.use(express.static(path.join(__dirname, 'public')));
app.get('/foo', (req, res) => {
// server the public folder again here
});
app.get('/bar/:id', (req, res) => {
// server the public folder again here
});
I'm trying to deploy a react app that uses routing. The problem is, I need to point all user-facing paths (so, /about, /contact, etc. but not /assets/images/icon.png) back to the homepage, because the react app uses react-router, and once the app is built for production and served as a static site, going to mysite.com/about gives a 404, where it wouldn't have before building.
So it turns out express.static("./path/to/site") can be the only argument to app.use(), or it can be the second argument.
Instead of using app.get(), I need to use app.use() for these other paths.
To capture all paths that weren't handled by default by the static site, I could have something like this:
app.use(express.static(path.join(__dirname, 'public')));
app.use('*', express.static(path.join(__dirname, 'public')));
To be more specific as in the question, I could have something like:
app.use(express.static(path.join(__dirname, 'public')));
app.use('/foo', express.static(path.join(__dirname, 'public')));
app.use('/bar/:id', express.static(path.join(__dirname, 'public')));
In that case, paths that aren't handled automatically by the static site and aren't listed afterwards will result in a 404.

Node JS Routing request

In server.js for specifying routing which is best method from below?
Method 1:
app.use('/', loginrouter);
app.use('/', logorouter);
app.use('/', headermenurouter);
app.use('/', hometaglinerouter);
app.use('/', howweworkrouter);
and then in each router file specify route
Method 2:
app.use('/login', loginrouter);
app.use('/logo', logorouter);
app.use('/headermenu', headermenurouter);
app.use('/hometagline', hometaglinerouter);
app.use('/howwework', howweworkrouter);
and then specifying route according to it in each seperate route file
If the sole reason to choosing a different router is the requested URI, go with option 2.

How to run middleware on all routes except static assets

Is there a way to run middleware on all express routes except for static assets?
I tried running it right in the app.use('/', authenticate, app.router()); but that leads to it running for all static assets as well.
Would I just have to list it on all my routes?
As #Explosion Pills points out in the comments,
add your middleware after the express.static middleware
Sample codes as below
app.use('/', express.static(path.resolve(root, './build/client')));
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true});
// ...
app.use('/', authenticate, app.router());

express.js: Route Function not called express.js

My express.js configuration looks like this:
//app.js:
var routes = require('./routes/index');
app.use(express.static(path.join(__dirname, '../client/build'), {'index': false}));
app.use('/', routes);
//routes/index.js:
router.get('/', function(req, res) {
console.log("im never called");
});
My handler is NEVER called (should be called when requesting without path or just '/'), the browser just gets a 303 with Location //, what is wrong here?
Thanks in advance for help!
Try to add module.exports = router; to the end of routes/index.js
Edit:
There is a common practice to put all your static files in one directory (maybe you have done it already) and make all requests to static files start with /public:
app.use('/public', express.static(path.join(__dirname, '../client/build'));
Doing this way
http://yoursite.com/public/some/file.js
will be served with
../client/build/some/file.js
Instead of /public you may choose a path that will not intersect with your router.
I was having this same issue this morning and I thought I would share my solution.
The express.static method is running on all of your requests... when it cannot find a match, it can either run the next() function and continue to your desired handler or redirect to a trailing slash to check if the request is for a directory.
I fixed it by adding 'redirect:false' as follows:
app.use(express.static(
path.join(__dirname, '../client/build'),
{index: false, redirect: false}));
Reference: express.static(root, [options])

In Express, what does app.router do exactly?

When I create a sample Express application using the express binary, the bootstrap code has these lines:
...
var app = express();
...
app.use(app.router);
I didn't find much about app.router. I thought that this is the middleware that handles the routing (app.get(), app.post() etc.) rules, but these rules also get executed when I remove the app.use(app.router); line.
So what is the exact purpuse of this middleware?
In Express 3.x, app.router is an enhanced version of the connect middleware router. As hector said, this is where Express handles the request handlers registered with app.get, app.post, etc.
If you do not call app.use(app.router) explicitly then express will call it implicitly the first time you use app.get(...), app.post(...), etc. However, you may want to .use it explicitly, because then you choose the order of all your middleware.
app.use(express.favicon());
app.use(express.bodyParser());
app.use(express.methodOverride());
// app.get, app.post, etc called before static folder
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
See how the router is retrieved in the Express 3 source here.
Note that Express 4 doesn't need app.router.
This is from the Express 2.x guide http://expressjs.com/2x/guide.html
"Note the use of app.router, which can (optionally) be used to mount
the application routes, otherwise the first call to app.get(),
app.post(), etc will mount the routes."
I suspect this applies to Express 3.x too.
In my case i wasn't exporting the module
module.exports = router;
This method has been deprecated
why we use router ..because of we need to connect our sub app to our main app.

Resources