Получить имя хоста текущего запроса в node.js Express

175

Итак, я могу упустить что-то простое здесь, но я не могу найти способ получить имя хоста, на который был запрошен объект запроса, на который я отправляю ответ.

Можно ли выяснить, какое имя хоста пользователь посещает в данный момент из node.js?

Джесси
источник
Это в заголовках запросов. Ну, я так и думал, но теперь я не вижу этого ...
хмммм
8
CJohn нашел это, это в request.headers.host- спасибо!
Джесси
Мысль так ... просто не вытащила его из олегина. Рад, что вы получили это!
Jcolebrand
@ Джесси Эй, это на самом деле не правильно. request.headers.host - это не имя хоста сервера в зависимости от ОС, это имя заголовка хоста, отправляемое вместе с HTTP-запросом. Если ваш сервер отвечает на любой HTTP-запрос независимо от заголовка узла, то это значение может быть НИЧЕГО, что клиент решит отправить.
Роб Эванс
@RobEvans - Если вы прочитали последнюю строчку вопроса, это именно то, что я искал. Клиент, отправляющий поддельный заголовок имени хоста, является причудливым вариантом использования, который я лично не буду беспокоиться о поддержке.
Джесси

Ответы:

198

Если вы говорите о HTTP-запросе, вы можете найти узел запроса в:

request.headers.host

Но это зависит от входящего запроса.

Больше на http://nodejs.org/docs/v0.4.12/api/http.html#http.ServerRequest

Если вы ищете машинную / нативную информацию, попробуйте объект процесса.

cjohn
источник
6
Ах, круто - FWIW, не было бы способа обнаружить реальный хост без запроса, вы могли бы настроить несколько хостов, но это то, что я искал!
Джесси
2
Сделал трюк, спасибо! В Express 4 я должен был сделать это обновление: req.headers.host
Джин Бо,
5
Неправильно! request.headers.hostвозвращает, http://127.0.0.1но не имя домена
Green
10
req.headers.hostпредоставляется пользователем. Я могу обработать запрос в 1 строке Python и отправить вам запрос без этого поля, что приводит к сбою вашего кода
arboreal84
1
request.headers.host устарела, вместо этого вы можете использовать request.headers.hostname
Syam Danda
281

Вы можете использовать модуль os:

var os = require("os");
os.hostname();

См. Http://nodejs.org/docs/latest/api/os.html#os_os_hostname

Предостережения:

  1. если вы можете работать с IP-адресом - у компьютеров может быть несколько сетевых карт, и если вы не укажете их, узел будет прослушивать все из них, поэтому вы не знаете, на какой сетевой адаптер поступил запрос, прежде чем он поступит.

  2. Имя хоста - это вопрос DNS. Не забывайте, что несколько псевдонимов DNS могут указывать на одну и ту же машину.

stephenbez
источник
6
Хотя это будет работать для получения имени хоста машины, я могу настроить машину так, чтобы она отвечала на несколько хостов, так что это не будет точным.
Джесси
7
Однако этот лучше - потому что вы можете использовать его в модулях, которые не всегда работают внутри контекста HTTP-приложения
Радагаст Браун
8
И что важно, этот отвечает на вопрос так, как он был написан. Я думаю, что вопрос на самом деле не так, если это не ответ.
Роб Эванс
3
Это соотносится с hostnameкомандой, которая должна быть допустимым DNS-именем, но не обязательна. Например, в OS X вы получите такие имена, my-machine.localкоторые невозможно решить с помощью DNS. Чтобы выяснить внешний IP-адрес компьютера, вам нужно обратиться к службе, которая выполняет эту функцию, или использовать протокол STUN, чтобы выяснить это.
tadman
6
Это всегда точно. Он возвращает имя хоста машины, которое является названием вопроса. (Текст этого задал другой вопрос). Имя хоста, используемое во входящем HTTP-запросе, является другим вопросом.
Cheeso
18

Вот альтернативный

req.hostname

Читайте об этом в Express Docs .

Эдди
источник
1
Это правильный ответ, так как req.headers.host дает host: port
ekerner
в чем разница между req.hostname и req.host
RayLoveless
1
req.host устарела. Если вы используете это, экспресс выдаст предупреждение «устаревший req.host: вместо этого используйте req.hostname»
bruceczk
8

Если вам нужно полное доменное имя и нет HTTP-запроса, в Linux вы можете использовать:

var child_process = require("child_process");

child_process.exec("hostname -f", function(err, stdout, stderr) {
  var hostname = stdout.trim();
});
dricket
источник
1
Кстати, hostnameв Windows есть также команда (но вы вызываете ее без параметров)
jakub.g
7

Прежде всего, прежде чем дать ответ, я хотел бы быть в курсе того факта, что доверяя заголовкам, вы открываете дверь уязвимостям безопасности, таким как фишинг. Поэтому для целей перенаправления не используйте значения из заголовков без предварительной авторизации URL-адреса.

Тогда имя вашей операционной системы может не совпадать с именем DNS. Фактически, один IP может иметь более одного DNS-имени. Таким образом, для целей HTTP нет гарантии, что имя хоста, назначенное вашему компьютеру в конфигурации вашей операционной системы, пригодно для использования.

Лучший выбор, который я могу придумать, - это получить публичный IP-адрес прослушивателя HTTP и разрешить его имя через DNS. Смотрите dns.reverseметод для получения дополнительной информации. Но опять же, обратите внимание, что IP может иметь несколько имен, связанных с ним.

arboreal84
источник