简体   繁体   English

Heroku 和 Google Cloud Run 上的 HTTP 请求不同

[英]HTTP request is not the same on Heroku and Google Cloud Run

I have a NodeJS/ExpressJS API that performs an HTTP request to get some JSON before sending a response.我有一个 NodeJS/ExpressJS API,它在发送响应之前执行 HTTP 请求以获取一些 JSON。 Here's the snippet of code:这是代码片段:

const ipApiUrl = `https://ipapi.co/${ip}/json/`
const ipApiResponse = await axios.get(ipApiUrl)
console.log(ipApiResponse.data)
ipCountryCode = ipApiResponse.data.country_code

This code works fine locally.此代码在本地运行良好。 It also works fine on Heroku.它在 Heroku 上也能正常工作。 However, it does NOT work the same on Google Cloud Run.但是,它工作在谷歌云上运行一样。

Here's what ipApiResponse.data should be:这是ipApiResponse.data应该是什么:

{
    "ip": "141.117.117.76",
    "city": "Toronto",
    "region": "Ontario",
    "region_code": "ON",
    "country": "CA",
    "country_code": "CA",
    ...
}

HOWEVER, when sending the request from Google Cloud Run the API I'm using returns something different.但是,当从 Google Cloud Run 发送请求时,我使用的 API 返回了不同的内容。 Instead I get this response:相反,我得到了这个回应:

{ ip: '169.254.8.129', reserved: true }

I think this problem is with either Google Cloud Run or Docker because I also have issues with making HTTP requests to other sites, like ipstack.com.我认为这个问题出在 Google Cloud Run 或 Docker 上,因为我在向其他站点(如 ipstack.com)发出 HTTP 请求时也有问题。

I am deploying to Google Cloud Run by using Docker.我正在使用 Docker 部署到 Google Cloud Run。 My Dockerfile is using node:10 and exposes the PORT environment variable like the documentation says.我的Dockerfile正在使用node:10并像文档所说的那样公开PORT环境变量。 Everything else works fine except for this HTTP request.除了这个 HTTP 请求,其他一切都正常。 I've tried both axios and fetch .我试过axiosfetch

You are sending a reserved IP address from the Private IP space.您正在从私有 IP 空间发送保留的 IP 地址。 This address is not valid on the public Internet.此地址在公共 Internet 上无效。 The returned response from IPAPI is correct. IPAPI 返回的响应是正确的。

IP Addresses in the CIRD block 169.254.0.0/16 are called an Automatic Private IP address. CIRD 块 169.254.0.0/16 中的 IP 地址称为自动专用 IP 地址。 An address in this range is typically used for local reserved network functions and for systems that automatically assign IP addresses without DHCP servers on the network.此范围内的地址通常用于本地保留网络功能和自动分配 IP 地址的系统,而无需网络上的 DHCP 服务器。 This address can also be assigned as a result of network failure.该地址也可能因网络故障而被分配。

The solution is to use a valid public IP address in your request to IPAPI.解决方案是在您对 IPAPI 的请求中使用有效的公共 IP 地址。 If your code is detecting this address, then you have a programming bug.如果您的代码正在检测此地址,那么您就有了编程错误。

Note: If you are trying to determine the IP address of your Cloud Run service by checking the network interface, you cannot.注意:如果您尝试通过检查网络接口来确定 Cloud Run 服务的 IP 地址,则无法确定。 Cloud Run is a service that runs behind load balancers call the Global Frontend (GFE). Cloud Run 是一种在负载均衡器后面运行的服务,称为全局前端 (GFE)。 You will need to use an external service to ask "what is my public IP address".您将需要使用外部服务来询问“我的公共 IP 地址是什么”。 The returned IP address will be for the GFE and not for your Cloud Run service.返回的 IP 地址将用于 GFE,而不用于您的 Cloud Run 服务。

To find a visitor's IP address on a Cloud Run application, you need to read the X-Forwarded-For header.要在 Cloud Run 应用程序上查找访问者的 IP 地址,您需要阅读X-Forwarded-For标头。

When you just look at the IP address on the request or TCP connection, you'll be seeing the internal IP address of the load balancer that sends the traffic to your application.当您只查看请求或 TCP 连接上的 IP 地址时,您将看到将流量发送到您的应用程序的负载均衡器的内部 IP 地址。 (169.254.xx is an internal IP address space defined in RFC 3927 , that's why you're seeing "reserved": true .) (169.254.xx 是RFC 3927 中定义的内部 IP 地址空间,这就是您看到"reserved": true 。)

So, in Express, try doing:因此,在 Express 中,尝试执行以下操作:

var ip = req.header('X-Forwarded-For')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM