Heroku 和 Google Cloud 运行 上的 HTTP 请求不同
HTTP request is not the same on Heroku and Google Cloud Run
我有一个 NodeJS/ExpressJS API 执行 HTTP 请求以在发送响应之前获得一些 JSON。这是代码片段:
const ipApiUrl = `https://ipapi.co/${ip}/json/`
const ipApiResponse = await axios.get(ipApiUrl)
console.log(ipApiResponse.data)
ipCountryCode = ipApiResponse.data.country_code
此代码在本地运行良好。它在 Heroku 上也能正常工作。但是,它 NOT 在 Google Cloud 运行.
上的工作方式相同
ipApiResponse.data
应该是这样的:
{
"ip": "141.117.117.76",
"city": "Toronto",
"region": "Ontario",
"region_code": "ON",
"country": "CA",
"country_code": "CA",
...
}
然而, 从 Google 云发送请求时 运行 API 我正在使用 returns 不同的东西.相反,我得到了这样的回应:
{ ip: '169.254.8.129', reserved: true }
我认为这个问题出在 Google Cloud 运行 或 Docker 上,因为我在向其他站点发出 HTTP 请求时也遇到了问题,例如 ipstack.com。
我正在使用 Docker 部署到 Google 云 运行。我的 Dockerfile
使用 node:10
并公开了 PORT
环境变量,如文档所述。除此 HTTP 请求外,其他一切正常。 axios
和 fetch
我都试过了。
您正在从私有 IP space 发送一个保留的 IP 地址。此地址在 public Internet 上无效。 IPAPI 返回的响应是正确的。
CIRD 块 169.254.0.0/16 中的 IP 地址称为自动私有 IP 地址。此范围内的地址通常用于本地保留网络功能,以及用于在网络上没有 DHCP 服务器的情况下自动分配 IP 地址的系统。该地址也可以因网络故障而分配。
解决方案是在您对 IPAPI 的请求中使用有效的 public IP 地址。如果您的代码正在检测此地址,那么您有一个编程错误。
注意:如果您试图通过检查网络接口来确定云 运行 服务的 IP 地址,则不能。云 运行 是一种在称为全球前端 (GFE) 的负载均衡器后面运行的服务。您将需要使用外部服务来询问 "what is my public IP address"。返回的 IP 地址将用于 GFE,而不用于您的云 运行 服务。
要在云 运行 应用程序上查找访问者的 IP 地址,您需要阅读 X-Forwarded-For
header。
当您只查看请求或 TCP 连接上的 IP 地址时,您会看到将流量发送到您的应用程序的负载平衡器的内部 IP 地址。 (169.254.x.x 是在 RFC 3927 中定义的内部 IP 地址 space,这就是您看到 "reserved": true
的原因。)
所以,在 Express 中,尝试做:
var ip = req.header('X-Forwarded-For')
我有一个 NodeJS/ExpressJS API 执行 HTTP 请求以在发送响应之前获得一些 JSON。这是代码片段:
const ipApiUrl = `https://ipapi.co/${ip}/json/`
const ipApiResponse = await axios.get(ipApiUrl)
console.log(ipApiResponse.data)
ipCountryCode = ipApiResponse.data.country_code
此代码在本地运行良好。它在 Heroku 上也能正常工作。但是,它 NOT 在 Google Cloud 运行.
上的工作方式相同ipApiResponse.data
应该是这样的:
{
"ip": "141.117.117.76",
"city": "Toronto",
"region": "Ontario",
"region_code": "ON",
"country": "CA",
"country_code": "CA",
...
}
然而, 从 Google 云发送请求时 运行 API 我正在使用 returns 不同的东西.相反,我得到了这样的回应:
{ ip: '169.254.8.129', reserved: true }
我认为这个问题出在 Google Cloud 运行 或 Docker 上,因为我在向其他站点发出 HTTP 请求时也遇到了问题,例如 ipstack.com。
我正在使用 Docker 部署到 Google 云 运行。我的 Dockerfile
使用 node:10
并公开了 PORT
环境变量,如文档所述。除此 HTTP 请求外,其他一切正常。 axios
和 fetch
我都试过了。
您正在从私有 IP space 发送一个保留的 IP 地址。此地址在 public Internet 上无效。 IPAPI 返回的响应是正确的。
CIRD 块 169.254.0.0/16 中的 IP 地址称为自动私有 IP 地址。此范围内的地址通常用于本地保留网络功能,以及用于在网络上没有 DHCP 服务器的情况下自动分配 IP 地址的系统。该地址也可以因网络故障而分配。
解决方案是在您对 IPAPI 的请求中使用有效的 public IP 地址。如果您的代码正在检测此地址,那么您有一个编程错误。
注意:如果您试图通过检查网络接口来确定云 运行 服务的 IP 地址,则不能。云 运行 是一种在称为全球前端 (GFE) 的负载均衡器后面运行的服务。您将需要使用外部服务来询问 "what is my public IP address"。返回的 IP 地址将用于 GFE,而不用于您的云 运行 服务。
要在云 运行 应用程序上查找访问者的 IP 地址,您需要阅读 X-Forwarded-For
header。
当您只查看请求或 TCP 连接上的 IP 地址时,您会看到将流量发送到您的应用程序的负载平衡器的内部 IP 地址。 (169.254.x.x 是在 RFC 3927 中定义的内部 IP 地址 space,这就是您看到 "reserved": true
的原因。)
所以,在 Express 中,尝试做:
var ip = req.header('X-Forwarded-For')