Django+Heroku环境下如何向Google地理定位API传递用户真实IP
解决Heroku部署Django后,Google地理定位API返回服务器位置的问题
你的核心问题是调用Google Geolocation API的方式错误——geolocate接口的considerIp和ipAddress参数不能放在URL查询串里,必须通过POST请求体传递,这就是明明拿到真实IP,却仍返回Heroku服务器位置的原因。
另外要注意,Heroku返回的HTTP_X_FORWARDED_FOR可能是逗号分隔的多IP串(比如用户真实IP, Heroku代理IP),直接取整串会拿到错误IP,得提取第一个值。
修正后的代码如下:
def get_latitude_longitude(request): # 获取用户真实IP,处理X-Forwarded-For的多IP格式 x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: # 取第一个IP并去除前后空格 ip_address = x_forwarded_for.split(',')[0].strip() else: ip_address = request.META.get('REMOTE_ADDR') # 基础API地址,仅保留API key在查询参数中 url = f"https://www.googleapis.com/geolocation/v1/geolocate?key={settings.GOOGLE_API_KEY}" # 构造请求体参数 payload = { "considerIp": True, "ipAddress": ip_address } # 发送带JSON请求体的POST请求 response = requests.post(url, json=payload) # 处理响应状态 if response.status_code != 200: print(f"API请求失败:{response.status_code} - {response.text}") return None, None, None, ip_address try: data = response.json() latitude = data['location']['lat'] longitude = data['location']['lng'] accuracy = data['accuracy'] return latitude, longitude, data, ip_address except KeyError as e: print(f"解析响应失败:缺失字段 {e}") return None, None, None, ip_address
关键修正点:
- 将
considerIp和ipAddress从URL查询参数移到POST请求的JSON体中,符合Google Geolocation API的调用规范 - 修复
HTTP_X_FORWARDED_FOR的解析逻辑,确保拿到用户真实IP而非代理IP - 添加基础异常处理,避免API返回异常导致程序崩溃
内容的提问来源于stack exchange,提问作者JimmyFl0
相关产品推荐
相关产品推荐

