Express.js 响应超时
Posted
技术标签:
【中文标题】Express.js 响应超时【英文标题】:Express.js Response Timeout 【发布时间】:2014-03-09 14:44:29 【问题描述】:问题
我一直在寻找 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 分钟。
【问题讨论】:
我只会将其用于开发目的——我想不出有一个用例可以让您使用空路由发送生产代码。 当然,我的观点是,它可能会出现请求会一直等待的问题。错误发生。我只是想设置一个响应超时以防万一。 知道了——见下面的答案 空路由作为网络蜘蛛的陷阱? 当我尝试使用 Express.js(实际上是 json-server)构建测试服务以模拟/诱导各种错误情况时,这个“功能”实际上非常有用在服务器端。大多数此类错误对应于 HTTP 状态代码(例如 Bad Request),是的,但我也想在调用方端引起 SocketTimeoutException。 【参考方案1】:已经有一个用于超时支持的连接中间件:
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();
如果您打算像上面那样将 Timeout 中间件用作***中间件,则 haltOnTimedOut
中间件需要是堆栈中定义的最后一个中间件,用于捕获超时事件。感谢@Aichholzer 的更新。
旁注:
请记住,如果您使用自己的超时中间件,则 4xx 状态码表示客户端错误,5xx 表示服务器错误。 408 保留用于以下情况:
在服务器准备等待的时间内,客户端没有产生请求。客户端可以在以后的任何时间重复请求而无需修改。
【讨论】:
完美。甚至更简单。也感谢有关错误消息的提示。 根据官方文档,不建议将其用作***中间件,至少不能这样。 github.com/expressjs/timeout 在不增加套接字超时的情况下,这个答案似乎毫无用处。 ***.com/questions/12651466/… @JeffFischer:调用socket.setTimeout()
只会增加调用超时事件之前的时间,但默认情况下不会切断连接nodejs.org/api/net.html#net_socket_settimeout_timeout_callback。在节点 v0.9.12 中,将 setTimeout API 添加到 http.server
对象中,以处理节点标准 http 库中此中间件的功能。但是,在 API 更新之前,此中间件将处理销毁套接字。你可以在这里阅读更多关于中间件的内容github.com/expressjs/timeout/blob/master/index.js
@SuperUberDuper:请将您的查询作为单独的问题发布,以便社区可以帮助您解决具体问题。【参考方案2】:
您不需要其他 npm 模块来执行此操作
var server = app.listen();
server.setTimeout(500000);
灵感来自https://github.com/expressjs/express/issues/3330
或
app.use(function(req, res, next)
req.setTimeout(500000, function()
// call back function is called when request timed out.
);
next();
);
【讨论】:
这是一篇很老的帖子,但我没有使用任何额外的模块。查看问题中的“修复”部分req.setTimeout
不是res.setTimeout
我的实验表明,req.setTimeout()
回调根本没有被调用,server.setTimeout()
没有关闭连接,也没有停止处理请求。所以提供的解决方案并不完整。
我的测试有 req.setTimeout
和 res.setTimeout
都可以工作。【参考方案3】:
如果使用 Express 4.2 的更新,则超时中间件已被删除,因此需要手动添加
npm install connect-timeout
并且必须在代码中(根据评论编辑,如何将其包含在代码中)
var timeout = require('connect-timeout');
app.use(timeout('100s'));
【讨论】:
没有DV,但有些人可能需要使用 var timeout = require('connect-timeout') 并且不得不在谷歌搜索它=)【参考方案4】:如果您想使用超时中间件并排除特定路由:
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
);
【讨论】:
【参考方案5】:request.setTimeout(< time in milliseconds >)
完成这项工作
https://nodejs.org/api/http.html#http_request_settimeout_timeout_callback
【讨论】:
【参考方案6】:你可以试试:
return await new Promise((resolve) =>
setTimeout(() =>
resolve(resp);
, 3000),
);
在上面的代码中,3000 = 3 秒。 根据您的要求更改它。
不过,我还没有尝试过很长时间的场景。让我知道 cmets 中的结果。
【讨论】:
【参考方案7】:在设置路线之前,添加代码:
app.all('*', function(req, res, next)
setTimeout(function()
next();
, 120000); // 120 seconds
);
【讨论】:
这不是等待120秒才回复客户吗? @JeffreyvanNorden 这就是我正在寻找的,用于调试目的。 讽刺的是,这正是我想要的。以上是关于Express.js 响应超时的主要内容,如果未能解决你的问题,请参考以下文章
Express.js 对 Angular CORS 错误的响应
Node.js - Express.js JWT 总是在浏览器响应中返回一个无效的令牌错误
在前端使用 fetch 从 express.js 服务器获取响应