HTTPS请求,指定主机名和特定的IP地址

时间:2018-11-28 15:19:32

标签: node.js https

我为我的应用程序服务器使用了基于Node.js的部署脚本。部署过程中的第一步是在向DNS注册之前,验证这些应用服务器是否正确侦听HTTPS。为此,我只需要向该服务器的IP地址发出HTTPS请求即可。

如果这是HTTP,则不是问题。我可以向GET发出HTTP http://[2001:0db8::0370:7334]/请求,这将起作用。但是,如果我为https://[2001:0db8::0370:7334]/发出HTTPS GET请求,则该操作将失败,因为证书是针对特定的主机名,例如api.example.com

如果我正在手动测试,我会暂时将IP地址放在hosts文件中,并在cURL https://api.example.com中输入。但是,在这种自动化过程中,我可能一次要部署多个主机,所以这不是我的部署脚本的解决方案。

如何在指定主机名和IP地址的地方发出HTTPS请求?

也许有某种方法可以通过自定义代理进行操作?

我目前正在使用node-fetch,但很高兴使用所需的API来完成这项工作。

1 个答案:

答案 0 :(得分:3)

设置请求的host标头:

const https = require('https');

https.get('https://AA.BB.CC.DD', {
  headers : { host : 'api.example.com' }
}, res => {
  console.log('okay');
}).on('error', e => {
  console.log('E', e.message);
});

编辑:我仔细研究了一下它的工作原理。为了允许基于HTTPS的虚拟主机,有一个称为SNI (Server Name Indication)的TLS扩展。客户端使用此扩展名来指示其尝试连接的主机名,以便服务器可以选择属于该主机名的适当证书。

tls使用的

Node的https模块具有选项servername来设置此主机名:

https.get('https://AA.BB.CC.DD', {
  servername : api.example.com'
}, ...)

但是,您仍然还需要传递Host标头(这是常规HTTP协议的一部分):

https.get('https://AA.BB.CC.DD', {
  headers : { host : 'api.example.com' },
  servername : 'api.example.com'
}, ...)

为使内容保持干燥,Node.js会将servername设置为Host标头,除非它已经设置为其他名称(here)。