res.sendFile() bit unique. If you don't pass it a completion callback, then it will call next() for you. See later in this answer for more details.
What you are reporting is the opposite of how Express says it works, so I think there should be something that is not quite the way you are reporting it.
The whole point of Express middleware is that any middleware call gets the opportunity to fill out a request, and then it either processes the request, generating a response, or if it wants the middleware chain to continue, then it calls next() , If next() not called, the middleware chain stops and nothing is called in the current middleware chain. If this is application-level middleware (with app.use() ), then there should be no additional middleware processing at the application level unless you call next() from your middleware.
Here's a quote from the Middleware Express Page :
If the current middleware does not complete the request-response cycle, it must call next () to transfer control to the next middleware, otherwise the request will be left hanging.
This is a pretty good article about Express: Express Middleware Demystified middleware that helps explain a lot more details. It also confirms that if you do not call next() , then no more handlers will be called in the middleware chain.
There is one special case with res.sendFile() . If you do not pass it a completion callback, it will call next() . If you pass it a completion callback, it will not call next() . This does not look well documented, but if you look at the res.sendFile() code here , you can see how it works.
One thing to consider when debugging is that sometimes the browser issues more requests than you can understand. For example, when you first got to the website’s homepage, the browser may ask for favicon, which causes an additional request to your web server. So, I am wondering if your debugging console.log() will confuse you, because maybe it includes more than one request, and not one request that goes through both middleware components. In addition, a cross-origin Ajax call may request AJAX parameters before requesting an actual Ajax call.
You can distinguish several requests like this, and more accurately see if it really goes from middleware1 to middleware2 for the same request:
var reqCntr = 1; app.use(middleware1); app.use(middleware2); function middleware1(req,res,next) { if (!req.reqCntr) { req.reqCntr = reqCntr++; } console.log("middleware1: " + req.reqCntr); ...//get extension of request URL switch (extension) { case 'js' : .. case 'html': res.sendFile(res.originalUrl,function(err) {}); // return here because the request is now handled return; case 'njm' : break; //break2 default : console.log('default'); break; } // the request was not handled so call the next link in the middleware chain next(); } function middleware2(req,res,next) { if (!req.reqCntr) { req.reqCntr = reqCntr++; } console.log("middleware2: " + req.reqCntr); }
Also, it seems that the middleware1 tags in which you are not processing the request should call next() , so for this I changed the middleware1 above. If you process the request in a switch statement, then return . If not, it will go to the next() call.