Laravel中如何通过动态获取的访客IP解析国家等地理位置信息
问题核心原因
你的代码解析失败是两个错误导致的:
- 调用位置查询时错误给IP拼接了
https://前缀,stevebauman/location的解析驱动只识别纯IP字符串,带协议前缀的内容会被判定为非法输入,直接返回空结果 - 如果项目部署在CDN、Nginx反向代理、负载均衡服务之后,默认的
request()->ip()拿到的是代理节点的IP,不是终端访客的真实IP,内网/保留IP段本身也没有公开地理位置信息
可直接落地的修复方案
- 先修正代理信任配置,打开
app/Http/Middleware/TrustProxies.php,修改$proxies属性值,确保框架能读取到访客真实IP:
protected $proxies = '*';
- 移除Location调用时多余的
https://前缀,增加解析结果空值判断,避免解析失败触发代码报错,修复后的业务代码如下:
$visitor = request()->ip(); $traffic = PageVisits::where('ip_address', $visitor) ->where('property_id', $id) ->whereMonth('created_at', Carbon::now()->month) ->first(); if(!(auth()->check() && auth()->user()->usertype == 'Admin')){ if (!$traffic) { $traffic = new PageVisits(); $traffic->ip_address = $visitor; $traffic->property_id = $id; // 直接传纯IP,不要加任何前缀 $position = Location::get($visitor); // 判空避免解析失败报错 if ($position) { $traffic->country = $position->countryName; // 国家名称 $traffic->country_code = $position->countryCode; // 国家编码 $traffic->postal_code = $position->postalCode; // 邮政邮编 $traffic->city = $position->cityName; // 城市 $traffic->region = $position->regionName; // 省份/地区 } $traffic->agency_id = $property->agency_id ?? ''; $traffic->save(); } }
补充说明
- 本地开发环境如果用
127.0.0.1、::1这类内网IP访问,解析会返回空,属于正常情况,部署到公网环境后即可正常返回结果 - 如果默认驱动解析精度不够,可以在
config/location.php中切换为MaxMind、GeoIP2等精度更高的驱动
内容的提问来源于stack exchange,提问作者Umar Waqar
相关产品推荐
相关产品推荐

