docker - Heroku 和 Google Cloud Run 上的 HTTP 请求不一样
问题描述
我有一个 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 上也可以正常工作。但是,它在 Google Cloud Run 上的工作方式不同。
这ipApiResponse.data
应该是:
{
"ip": "141.117.117.76",
"city": "Toronto",
"region": "Ontario",
"region_code": "ON",
"country": "CA",
"country_code": "CA",
...
}
但是,当从 Google Cloud Run 发送请求时,我正在使用的 API 返回一些不同的东西。相反,我得到了这个回应:
{ ip: '169.254.8.129', reserved: true }
我认为这个问题出在 Google Cloud Run 或 Docker 上,因为我在向其他站点(如 ipstack.com)发出 HTTP 请求时也遇到了问题。
我正在使用 Docker 部署到 Google Cloud Run。我Dockerfile
正在使用node:10
并公开PORT
环境变量,如文档所述。除了这个 HTTP 请求之外,其他一切都很好。我都试过了axios
和fetch
。
解决方案
要在 Cloud Run 应用程序上查找访问者的 IP 地址,您需要阅读X-Forwarded-For
标头。
当您只查看请求或 TCP 连接上的 IP 地址时,您将看到将流量发送到您的应用程序的负载均衡器的内部 IP 地址。(169.254.xx 是RFC 3927中定义的内部 IP 地址空间,这就是您看到的原因"reserved": true
。)
因此,在 Express 中,尝试执行以下操作:
var ip = req.header('X-Forwarded-For')
推荐阅读
- android - Deezer 播放流延迟
- java - 我选择的货币符号没有出现在屏幕上
- vuejs2 - 在 Vuetify 中为使用 prepend-icon 定义的图标设置样式
- docker - 在 Gitlab CI 中使用 docker 图像时,我如何尊重服务的别名
- angular - 插件 Base64 不适用于 ionic 3
- angular - 无法读取角度 4 中未定义值的属性
- dns - 服务名称在主节点而不是其他节点上解析
- android - Google Play Console - 翻译服务:我可以在 xml 文件中描述我的字符串吗?
- python - 完成测试后,用分类模型预测重新填充数据框的替代方法?
- android - 对于 Android,我如何从 SQLite 中的日期和日期范围获取数据,其中 Android 变量可以传递给查询?