Js 响应超时

问题

我一直在寻找 Express.js 的请求/响应超时,但似乎一切都与连接有关,而不是与请求/响应本身有关。

如果一个请求花费了很长时间,那么它应该超时。显然,这种情况不应该发生,但即使是一个简单的错误,比如拥有一个没有调用回调或没有 res.send()的路由处理程序,浏览器也会永远等待回复。

空路由处理程序就是一个很好的例子。

app.get('/sessions/', function(req, res, callback){});

修正

我添加了以下 之前 app.use(app,router);,它似乎添加了超时功能。有人对此有什么经验或看法吗?

app.use(function(req, res, next){
res.setTimeout(120000, function(){
console.log('Request has timed out.');
res.send(408);
});


next();
});

注意,我将超时时间设置为2分钟。

177967 次浏览

There is already a Connect Middleware for Timeout support:

var timeout = express.timeout // express v3 and below
var timeout = require('connect-timeout'); //express v4


app.use(timeout(120000));
app.use(haltOnTimedout);


function haltOnTimedout(req, res, next){
if (!req.timedout) next();
}

If you plan on using the Timeout middleware as a top-level middleware like above, the haltOnTimedOut middleware needs to be the last middleware defined in the stack and is used for catching the timeout event. Thanks @Aichholzer for the update.

Side Note:

Keep in mind that if you roll your own timeout middleware, 4xx status codes are for client errors and 5xx are for server errors. 408s are reserved for when:

The client did not produce a request within the time that the server was prepared to wait. The client MAY repeat the request without modifications at any later time.

An update if one is using Express 4.2 then the timeout middleware has been removed so need to manually add it with

npm install connect-timeout

and in the code it has to be (Edited as per comment, how to include it in the code)

 var timeout = require('connect-timeout');
app.use(timeout('100s'));

Before you set your routes, add the code:

app.all('*', function(req, res, next) {
setTimeout(function() {
next();
}, 120000); // 120 seconds
});

request.setTimeout(< time in milliseconds >) does the job

https://nodejs.org/api/http.html#http_request_settimeout_timeout_callback

You don't need other npm modules to do this

var server = app.listen();
server.setTimeout(500000);

inspired by https://github.com/expressjs/express/issues/3330

or

app.use(function(req, res, next){
req.setTimeout(500000, function(){
// call back function is called when request timed out.
});
next();
});

In case you would like to use timeout middleware and exclude a specific route:

var timeout = require('connect-timeout');
app.use(timeout('5s')); //set 5s timeout for all requests


app.use('/my_route', function(req, res, next) {
req.clearTimeout(); // clear request timeout
req.setTimeout(20000); //set a 20s timeout for this request
next();
}).get('/my_route', function(req, res) {
//do something that takes a long time
});

You can try:

return await new Promise((resolve) =>
setTimeout(() => {
resolve(resp);
}, 3000),
);

In above code, 3000 = 3 sec. Change it according to your requirement.

I have not tried for very long scenarios though. Let me know the results in comments.

If you need to test your api, this solotion can you help. I used this in middleware to test my frontend. For exmaple: if you need to test loader in frontend.

const router = require('express').Router();
const { data } = require('./data');


router.get('/api/data', (req, res, next) => {
setTimeout(() => {
res.set('Content-Type', 'application/json')
res.status(200).send(data)


next()
}, 2000)
})


module.exports = router;