Node.js Express:从req对象中获取带有端口的主机名

9
有时我想从我的节点应用程序中通过邮件发送一个合格的URL。或者我想设置幻像页面对象的内容。
在我的部署设置中,我可以这样获取完整的URL。
'http://' + req.hostname + '/myapp'

然而,在开发机器上,这通常会产生:

http://localhost/myapp 而不是 http://localhost:3000/myapp

我知道如何获取端口,但我不想使用像下面这样的东西:

'http://' + req.hostname + ':' + port + '/myapp'

如果在代理后部署,将会产生像这样的无意义内容。

http://domain.com:3000/myapp

如果应用程序在代理外运行,是否有一种聪明的方法从请求对象中获取主机名和端口?

2个回答

10

我不确定为什么Express Request弃用了 host,但这段代码是一个安全的解决方案,可以解决在代理后/未代理后运行Express服务器的问题。


const proxyHost = req.headers["x-forwarded-host"];
const host = proxyHost ? proxyHost : req.headers.host;

我发现这种方式在构建“返回”URL时非常有用,特别是涉及到重定向的工作流程,例如OAuth 2。


3
您需要查找的是X-Forwarded-For header。如果您在代理、负载均衡器等后面,则这是获取原始url的最安全方法。检查请求中是否存在此内容,如果存在,则使用它,否则使用已经实现的内容。
这个express源码将会很有帮助:
  • req.hostname的值来自于X-Forwarded-Host标头中设置的值,可以由客户端或代理服务器设置。

  • X-Forwarded-Proto可以被反向代理设置为告诉应用程序它是https还是http甚至是无效名称。此值由req.protocol反映。

  • req.ip和req.ips值由X-Forwarded-For中的地址列表填充。


4
是的,我正在做这件事。正如所提到的,在部署中一切都按照预期工作。问题只存在于我的开发平台上。所以目前我已经硬编码了 localhost:3000,并在推送到版本控制之前切换注释。它能够工作,但不够优雅,因此我的问题是是否有更聪明的方法来让本地开发就像部署一样运行。 - Dennis Bauszus

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