Вы можете сделать res.json()
только один раз. Рассмотрим следующий пример:
var express = require('express');
var app = express();
app.get('/json1', function (req, res) {
setTimeout(function() {
res.json({ok:true});
}, 2000);
});
app.get('/json2', function (req, res) {
setTimeout(function() {
res.json({ok:true});
res.json({ok:true});
}, 2000);
});
app.listen(3333);
Когда вы к нему доступ:
$ curl http://localhost:3333/json1
Вы получаете это через 2 секунды:
{"ok":true}
Но если вы пытаетесь получить к нему доступ с:
curl http://localhost:3333/json2
Тогда вы все равно получите это на своем c lient сторона:
{"ok":true}
Но ваши аварии сервера с:
_http_outgoing.js:344
throw new Error('Can\'t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11)
Это означает, что Экспресс ждет res.json()
и завершает запрос, как только он получает один, но после этого момента вы не можете назвать это второй раз.
То же самое происходит с res.send()
- например.см эти маршруты:
app.get('/send1', function (req, res) {
setTimeout(function() {
res.send('ok');
}, 2000);
});
app.get('/send2', function (req, res) {
setTimeout(function() {
res.send('ok');
res.send('ok');
}, 2000);
});
С другой стороны, кажется, что вы можете назвать res.end()
дважды, и второй вызов игнорируется:
app.get('/end1', function (req, res) {
setTimeout(function() {
res.end('ok');
}, 2000);
});
app.get('/end2', function (req, res) {
setTimeout(function() {
res.end('ok');
res.end('ok');
}, 2000);
});
Но если вы используете res.write()
вместо res.end()
то запрос будет ждать res.end()
и никогда не закончить:
app.get('/end1', function (req, res) {
setTimeout(function() {
res.end('ok');
}, 2000);
});
app.get('/end2', function (req, res) {
setTimeout(function() {
res.end('ok');
res.end('ok');
}, 2000);
});
Но сообщение на самом деле доставляется - что у НУ может наблюдать, прекратив сообщение от «\ п», чтобы сделать curl
показать его, когда он приходит:
app.get('/write1', function (req, res) {
setTimeout(function() {
res.write('ok\n');
}, 2000);
});
app.get('/write2', function (req, res) {
setTimeout(function() {
res.write('ok\n');
res.write('ok\n');
}, 2000);
});
Так как вы можете видеть, есть определенные способы передачи данных - как res.write()
, которые могут быть использованы многократно и не закрывает соединение. Существуют и другие способы, такие как res.json()
, которые могут использоваться только один раз, и они неявно закрывают соединение.
Но если добавить маршрут, как это:
app.get('/empty', function (req, res) {
});
Тогда Экспресс будет ждать вечно с открытым подключением, потому что он не имеет возможности сказать ли res.end()
или res.json()
будет называться в будущем. Он может знать только, был ли он уже назван или нет.
Таким образом, соединение поддерживается открытым до тех пор, –
@CallumLinington Да. Но для тайм-аута (на стороне Express) вам нужно использовать промежуточное ПО, например 'connect-timeout', с' var timeout = require ('connect-timeout'); app.use (timeout ('5s')); 'или что-то в этом роде. В противном случае Express будет ожидать, вероятно, тайм-аута на стороне клиента или таймаута TCP-соединения. – rsp
О да, это жемчужина! –