Express middleware refrain static from going into next - node.js

I have the following function:
app.use('/Framework', express.static(path.resolve(__dirname, 'Framework')));
app.get('/*/*', function (req, res, next) {
...code...
);
The request goes into both the app.use and the app.get. I'd like it that when I try to access a resource with /Framework it just gives it to me as static while ignoring the other functions from below. Yet when accessing static it seems to go in the app.get.
Why is this happening and how can I modify it to get the wanted behavior?
Edit due to comment
I also have a
app.use('/Public', express.static(path.resolve(__dirname, 'Public')));
before which works perfectly as expected.
Requests such as : /Public/0.png work while requests such as /Framework/0.png enter both functions. I have checked the folders names over and over again and they are correct.

Express-static is Express middleware. Middleware is chained together and after a middleware is done executing its code, it calls next(); internally to allow the next middleware to execute. After all middleware is executed, the routes will be executed.
Since express-static calls next(); after its done, the routes will be invoked and checked if any routes match the request. Since your request /Public/0.png matches your route /*/* the route is executed.
My suggestion would be to try an rename your route from /*/* to something more specific.
You could try regex for the route which would explicitly allow any requests matching /*/* but would refuse any routes which have a file extension appended to it (i.e. /*/*.png).
Another (hacky) way would be to check for headersSent inside your /*/* route before executing the code within that route.
A side-note:
Seeing how your route name (e.g. Public and Framework) are the same as your directory names, you could simply do
app.use('/', express.static(path.resolve(__dirname, PARENT_DIRECTORY)));
Where PARENT_DIRECTORY is the parent directory of both Public and Framework. This way
Your directory structure would look like this:
Directory
|
| ---- Public
| ---- Framework
And any requests to Public would end up serving files from your Public directory, same for the Framework directory respectively.

Related

How to prevent express server from serving api routes from the static folder

Hi I need some help with how express handles routes.
In setting up my express app, I have something like this:
app.use(express.static('public'));
Next, I mount some api routes:
app.use('/api', myrouter);
app.get('*', function(req, res) {
res.sendFile(path.resolve('public/index.html'));
});
But, when the frontend requests data via an api route, e.g. at 'localhost:3000/api/things', I am seeing in the Express debug logs that at some point (unsure when) it actually tries to serve this request as a static file, like:
send stat "C:\myproject\public\api\things" +230ms
Even though this folder doesn't exist in 'public' and should be solely handled by my api. FYI, the handler for /api/things route is only implemented for the GET method, and does get invoked at some point.
How do I stop express server from also trying to serve api requests from the static folder?
Thanks very much.
Answering my own question... which appears to be a duplicate of this one:
`express.static()` keeps routing my files from the route
So the answer is this one: https://stackoverflow.com/a/28143812/8670745
In short, the app.use() declarations that mount your api routers should appear before the app.use() statements which tell express.static where to serve your static files from. This way, the latter acts as a catchall AFTER api route handling is done. Router engine order matters...
Your answer is misinformed, or rather you've misinterpreted the problem. Your original configuration:
app.use(express.static(__dirname + 'public'));
app.use('/api', myrouter);
Looks absolutely fine because there's no clash between the routes. The threads you've linked too aren't really the same, and I can see why moving the routes in those cases would have worked.
The only thing I'd say is your path to your static folder isn't reliable, you should really use path.join, or actually in your case you can just do express.static('public') - express will infer the folder your app is served from.

nodeJs/Express dealing with missing static files

I have a node App. That is configured to serve static files by:
app.use(express.static(path.join(__dirname, '../public')));
And I use some auth middlewares on other routes. The problem comes up when I hit an image that doesn't exist on the server. In this case looks like express is trying to send that request through all of the middlewares that I have for NON-static content.
Is there a way to just send 404 for missing static asset, rather than re-trigger all middlewares per missing file?
The way that the express.static() middleware works by default is that it looks for the file in the target directory and if it is not found, then it passes it on to the next middleware.
But, it has a fallthrough option that if you set it to false, then it will immediately 404 any missing file that was supposed to be in the static directory.
From the express.static() doc:
fallthrough
When this option is true, client errors such as a bad request or a
request to a non-existent file will cause this middleware to simply
call next() to invoke the next middleware in the stack. When false,
these errors (even 404s), will invoke next(err).
Set this option to true so you can map multiple physical directories
to the same web address or for routes to fill in non-existent files.
Use false if you have mounted this middleware at a path designed to be
strictly a single file system directory, which allows for
short-circuiting 404s for less overhead. This middleware will also
reply to all methods.
Example:
app.use("/public", express.static("/static", {fallthrough: false}));

Express: Index Route not called when index.html is served statically

node v5 express 4.13.3
What I did:
I was serving out the index.hmtl file when the index route("/") was hit. I then set it the public folder to be sent out as a static file.
What Problem it Caused:
Now that it is static, my index route is no longer entered when the browser opens the index route e.g.(localhost:3000/)
Question:
Is that expected behavior? Is it a good idea to serve index.html statically ?
Is that expected behavior?
Yes. Express will pass a request through the list of middleware (including your own index route), and if one of those can handle the request, it will and the request will finish (it won't get passed to other middleware).
The static middleware can handle the request for the index (presumably because you have an index.html in your public directory), so the request will end there and not get passed to your handler as well.
The order in which requests are passed to middleware is something that you can control. If you want your own index handler to get a higher priority, you should declare it before the static middleware:
app.get('/', function(req, res) {
...
});
app.use(express.static(...));
Is it a good idea to serve index.html statically ?
If it's plain HTML and there's nothing else that needs to be done when it's requested, it's probably best to let the static middleware handle it.

How to use static folder but also use routing in Express?

I'm having a major issue with Routing in Express.
In my project, there is a folder /public.
Inside /folder I have some other folders like
- public
|- user
|- common
Initially, the only way pages were served by my Node.js server was through res.sendFile(../..). The problem was that the .js files and .css files did not know where to go.
So I added
app.use('/', express.static(__dirname + '/public'));
But now the problem is, if I try to visit /user what happens is, that the static version of the index.html file in that folder is returned, and my route defined in the node app is ignored!
This route - and most importantly the auth middleware is never touched!
How do I reconcile the need to serve files from a static folder, but also may have routes of the same name that I want to control more closely?
app.use('/user', userauth, userRoutes);
Assuming /user is some sort of API I don't think express.static was intended to be used that way. I think the best solution would be to use different routes. You could add something like /api/ to the beginning of all your routes or make sure your static files are organized under /css, /js, /partials, etc.
If you absolutely must support /user for static files AND your api calls you will need to ditch express.static and use something like the Accept header with custom middleware that determines what the browser is asking for. Depending on the scenario this may get complicated to support all the variables. A simple example would be something like this:
app.use(function(req, res, next){
// check Accept header to make sure its a JSON request
if(req.accepts('application/json') && !req.accepts('html')) {
// JSON request so forward request on to the next middleware(eventually hitting the route)
return next();
}
// NOT a JSON request so lets serve up the file if it exists...
// TODO use req.path to check if file exists - if not 404 - will also need to map paths
// to /users to check for /users/index.html if you need to support that
var fileExists = false;
return fileExists ? res.sendFile('...') || res.status(404).send('Not Found');
});
You would have to make sure when the client calls /users it sets the Accept header to application/json. Most client side frameworks have a way to do this for all AJAX requests.

Using middleware with express().use along with express.static

I'm using PassportJS to secure a WebApp (written with AngularJS). I'm using NodeJS with Express (4.0.0) to serve static content after the login-screen. I don't get how to use a middleware along with express.static() at the same time.
My (not working) code looks like
app.use('/secure',
function (req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
},
express.static(__dirname + '/../../client'));
The plan is, that the middleware ensures, that the user is only forwareded to the WebApp if he/she is logged in. If not, he/she/it is redirected to the root folder.
I found this answer, but according to the documentation, the new version supports multiple functions. This isn't the "clean" solution I'm looking for, since the directory contains too many subfolders and files.
Thanks in advance
When you attach middlewares to the same route they get executed in the same order of declaration, so if you want to execute any middleware before express.static, all what you have to do is attach it to the same route and declare it before.
app.use('/secure', myMiddleWare);
app.use('/secure', express.static(__dirname + '/../../client'));

Resources