#javascript #node.js #express
#javascript #node.js #экспресс
Вопрос:
Извините за плохое название, но я не смог придумать ничего лучше. Сначала взгляните на следующий фрагмент кода:
app.use(function(request, response){
request.addListener('end', function() {
parseUrl(request.url, function(urlInfo) {
if (urlInfo.notFound)
response.send(404);
else if (urlInfo.extension == '.html') {
response.render(
urlInfo.path,
{
file: urlInfo.filenameWithoutExtension,
url: urlInfo.url,
directory: urlInfo.directory
},
function(error, html) {
if (error) {
console.log("Error rendering view: " error);
response.send(404);
}
response.send(html);
});
}
else
file.serve(request, response);
});
}).resume();
});
Этот код выполняется нормально и обслуживает страницы. Для определенных запросов parseUrl выполнит вызов веб-службы. Результат этой службы определяет, следует ли нам отправлять ответ 404 клиенту или нет. Таким образом, когда необходимо вызвать службу, обратный вызов вызывается после веб-запроса, в противном случае обратный вызов вызывается просто встроенным.
Код выполняется нормально, но я получаю ответ 200. Просматривая файлы журнала, выясняется, что response.send(404) вызывается после отправки ответа 200. Итак, я предполагаю, что request.resume() вызывается во время выполнения веб-запроса. Это действительно имеет смысл.
Однако, что бы я ни делал, я не могу заставить это функционировать так, как я хочу. Я пытался:
- Перемещение запроса.resume в конец обратного вызова
- Удаление app.use и выполнение request.resume в конце обратного вызова.
Обычно, что бы я ни делал, я прерываю работу сервера, и либо истекает время ожидания, либо возникают ошибки.
Я просмотрел веб-страницы и нахожусь в недоумении. Если кто-нибудь сможет указать мне правильное направление, я был бы очень признателен. Очевидно, что мне здесь не хватает важной части знаний, я новичок в node и express, это мой первый проект.
Заранее спасибо.
Приветствую, Марк
ОБНОВЛЕНИЕ: просматриваем это еще раз и читаем https://github.com/joyent/node/blob/master/doc/api/stream.markdown . Кажется, мне нужно явно вызвать pause в конечном событии при использовании асинхронного обратного вызова, иначе поток закроется при возвращении. Я попробую это позже сегодня и отчитаюсь.
Комментарии:
1. попробуйте сказать
return
после этой строкиresponse.send(404);
.2. Хотя я не думал, что это сработает, я просто попробовал, и это не имело никакого значения. Однако спасибо за ваш быстрый ответ.
3. Просто я думал, что эта
response.send(html);
строка будет вызываться каждый раз, даже если возникает ошибка. Так я и думал…4. Mritunjay: Да, действительно, это ошибка, просто не та ошибка, которую я искал 🙂
Ответ №1:
Это был просто вопрос приостановки потока запросов на время выполнения асинхронного вызова. В итоге мой метод закончился так:
app.use(function(request, response){
request.on('end', function() {
var parseStatus = parseUrl(request.url, function(urlInfo, status) {
if (urlInfo.notFound)
response.send(404);
else if (urlInfo.extension == '.html') {
response.render(
urlInfo.path,
{
file: urlInfo.filenameWithoutExtension,
url: urlInfo.url,
directory: urlInfo.directory
},
function(error, html) {
if (error) {
console.log("Error rendering view: " error);
response.send(404);
}
else
response.send(html);
});
} else
file.serve(request, response);
if (status.executedAsynchronously)
request.resume();
});
if (parseStatus.executedAsynchronously)
request.pause();
}).resume();
});
Комментарии:
1. Не забудьте установить для ответа StatusCode = 404
2. Почему? Согласно документации по expressjs.org любое число, переданное в res.send(), будет интерпретироваться как код состояния.