Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

After sending response, how to end the current request processing in Node/Express?

There are a few posts on this question but none that answers the issue directly, head-on. Let me clarify that I understand (or so I think) the use of next(), next('route'), return next(), return and their impact on control flow. My entire middleware for the app consists of a series of app.use, as in:

 app.use(f1);
 app.use(f2);
 app.use(f3);
 app.use(f4);
 ...

In each of these middlewares, I have possibility of sending the response and be done without any need for further processing. My problem is that I am unable to stop the processing from going to the next middleware.

I have a clumsy work around. I just set a res.locals.completed flag after sending a response. In all the middlewares, at the very start, I check this flag and skip processing in the middleware if the flag is set. In the very first middleware, this flag is unset.

Surely, there must be a better solution, what is it? I would think that Express implicitly would do this checking and skip the middlewares through some express-specific method?

like image 832
Sunny Avatar asked Nov 11 '15 10:11

Sunny


People also ask

How do I end a Nodejs response?

end() function is used to end the response process. This method actually comes from the Node core, specifically the response. end() method of HTTP. ServerResponse.

How do I stop res after sending?

You only need to do a return to end the flow: return res. send( 401 ); That will send the 401 response back and won't proceed forward in the flow.

How do I stop a node js request?

Update: If you're using Node. js >= v16. 14.0 and want to cancel an HTTP request after a specific amount of time, I'd recommend using the AbortSignal. timeout() method.


1 Answers

According to the express documentation on http://expressjs.com/guide/using-middleware.html

If the current middleware does not end the request-response cycle,
it must call next() to pass control to the next middleware,
otherwise the request will be left hanging.

so if a middleware needs to end the request-response early, simply do not call next() but make sure that the middleware really ends the request-response by calling res.end, res.send, res.render or any method that implicitely calls res.end

app.use(function (req, res, next) {
  if (/* stop here */) {
    res.end();
  } else {
    next();
  }
});

Here is an example server showing that it works

var express = require('express');
var app = express();

var count = 0;
app.use(function(req, res, next) { 
  console.log('f1'); 
  next();
 })
app.use(function(req, res, next) {
  console.log('f2');
  if (count > 1) {
    res.send('Bye');
  } else {
    next();
  }
})
app.use(function(req, res, next) {
  console.log('f3');
  count++;
  next();
})

app.get('/', function (req, res) {
  res.send('Hello World: ' + count);
});

var server = app.listen(3000);

you will see the after 3 requests, the server shows "Bye" and f3 is not reached

like image 163
Jerome WAGNER Avatar answered Sep 30 '22 19:09

Jerome WAGNER