在node.js Express中获取当前请求的主机名

222

所以,也许我错过了一些简单的东西,但是我似乎找不到一种方法来获取请求对象的主机名,这个请求对象是我正在向其中发送响应。

在node.js中是否有可能确定用户当前正在访问的主机名?


15
CJohn 找到了,它在 request.headers.host 中 - 感谢! - Jesse
@RobEvans - 如果您读取问题的最后一行,那正是我所寻找的。客户端发送虚假主机名标头是一个奇怪的用例,我个人不会担心尝试支持它。 - Jesse
可能是如何使用ExpressJS检查HOST?的重复问题。 - niry
@niry 绝对不是重复问题,你链接的那个问题是在尝试检查子域名,而且那个问题和答案的质量都远远低于这个问题。我该如何摆脱这个烦人的重复标语? - Jesse
我认为这个帖子是关于这个特定主题的 Stack Overflow 的规范帖子。为了继续帮助那些发现下面两个答案有用的人,我不会亲自将这个问题关闭为重复。管理员可以随意处理。 - Jesse
显示剩余4条评论
8个回答

291

你可以使用os模块:

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

请查看http://nodejs.org/docs/latest/api/os.html#os_os_hostname

注意事项:

  1. 如果您可以使用IP地址 -- 机器可能有多个网络卡,除非指定,否则Node将在所有网络卡上监听,因此在请求进入之前,您不知道请求是从哪个网卡进入的。

  2. 主机名是DNS问题 -- 别忘了多个DNS别名可以指向同一台机器。


7
虽然这种方法可以获取机器的主机名,但我可能会设置一台机器来响应多个主机名,因此这种方法就不太准确了。 - Jesse
7
这个更好,因为你可以在模块中使用它,而这些模块不一定总是在 HTTP 应用程序的上下文中运行。 - Radagast the Brown
8
重要的是,这个回答按照问题的原意进行了回答。如果不是这个答案,我认为问题实际上是错误的。 - Rob Evans
3
这与hostname命令相关,该命令应该是一个有效的DNS名称,但不一定要求是。例如,在OS X下,你会得到像my-machine.local这样的名称,它无法通过DNS解析。如果想找到机器的外部IP,则需要访问执行此功能的服务或使用STUN协议来找到它。 - tadman
6
这个永远准确。它返回机器的主机名,这就是问题标题所问的内容。(但这个问题的文字问了另一个问题)。在传入的HTTP请求中使用的主机名是另一回事。 - Cheeso
显示剩余6条评论

264

6
啊,太棒了 - 顺便说一下,没有请求就无法检测到实际主机,您可以配置多个主机,但这就是我要找的! - Jesse
2
行了,谢谢! 在Express 4中,我必须执行此更新:req.headers.host - Gene Bo
7
错误!request.headers.host返回的是http://127.0.0.1而不是生产服务器的域名。 - Green
14
req.headers.host 是由用户提供的。我可以用一行 Python 代码构造一个请求给你,并在不包含该字段的情况下发送此请求,而不会导致你的代码崩溃。 - arboreal84
4
request.headers.host 已经过时,可以使用 request.headers.hostname 代替。 - Syam Danda
显示剩余4条评论

48

这里提供一个替代方案

req.hostname

Express文档中了解相关信息。


5
这是正确答案,因为req.headers.host会给出host:port。 - ekerner
req.hostname和req.host有什么区别? - RayLoveless
1
req.host已被弃用。如果您使用它,express将输出一个警告,提示“已弃用req.host:请改用req.hostname”。 - bruceczk

9
如果您需要一个完全限定的域名并且没有HTTP请求,在Linux上,可以使用以下命令:

hostname --fqdn

var child_process = require("child_process");

child_process.exec("hostname -f", function(err, stdout, stderr) {
  var hostname = stdout.trim();
});

1
顺便提一下,在Windows中也有hostname命令(但是你不需要带参数调用它)。 - jakub.g
1
@jakub.g 是的,但是它不返回完全限定的主机名。 - fourpastmidnight

8
首先,在提供答案之前,我想要坦言的是,通过信任标头,您打开了安全漏洞的大门,例如网络钓鱼。因此,在重定向目的中,请勿在未验证URL已获得授权之前使用来自标头的值。
其次,您的操作系统主机名可能不一定与DNS名称匹配。事实上,一个IP地址可能有多个DNS名称。因此,对于HTTP目的,无法保证在操作系统配置中分配给您的计算机的主机名可用。
我能想到的最好选择是获取HTTP监听器的公共IP,然后通过DNS解析其名称。有关更多信息,请参见dns.reverse方法。但请注意,一个IP可能有多个关联的名称。

2
您可以直接使用以下代码来获取主机名。
request.headers.host

1

我认为你希望识别跨域请求,此时你需要使用 Origin 头信息。

const origin = req.get('origin');

使用此功能可以获取客户端 URL 请求。


0

你可以从requestheaders中获取客户端的URL,其中有一个属性叫做origin。因此:

request.headers.origin

对我来说,这是未定义的,可能只适用于特定类型的请求。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接