做前端开发的朋友,谁没被“获取本地IP”这个问题折磨过?

尤其是现在浏览器安全策略越来越严,以前那种直接调API的方法基本都废了。

今天我就掏心窝子说说,怎么在真实项目中优雅地拿到这个值,顺便把坑都填了。

先说结论:纯前端JS根本不可能直接获取真实的局域网IP,这是浏览器为了隐私做的限制。

别信网上那些让你用WebRTC或者Flash的老黄历,那都是几年前的老皇历了。

现在的Chrome和Firefox,早就把这些权限封得死死的。

那怎么办?

只能曲线救国,分两步走。

第一步,后端接口辅助。

这是最稳妥、最通用的做法。

你在Node.js或者Python后端写个简单的接口,直接读取请求头里的IP。

比如Node.js里,req.connection.remoteAddress就能拿到。

但这里有个大坑,如果你用了Nginx做反向代理,拿到的可能是127.0.0.1或者内网IP。

这时候必须配置Nginx的proxy_set_header X-Real-IP $remote_addr;

不然你前端拿到的永远是网关地址,根本没法用。

第二步,前端WebRTC探测。

这个方案适合那些不想依赖后端,或者后端搞不定的场景。

原理是利用WebRTC在建立P2P连接时,会暴露本地的候选地址。

代码大概长这样:

var pc = new RTCPeerConnection();

pc.createDataChannel("");

pc.createOffer().then(function(offer) {

return pc.setLocalDescription(offer);

}).then(function() {

return new Promise(function(resolve) {

setTimeout(resolve, 500);

});

}).then(function() {

var sdp = pc.localDescription.sdp;

var ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g;

var ips = sdp.match(ipRegex);

console.log(ips);

});

这段代码看着挺高大上,但实际操作中,你会发现它并不稳定。

有时候能拿到,有时候拿不到,有时候拿到的是IPv6地址,甚至可能是虚拟网卡地址。

我有个客户的项目,就是用这个方案,结果在华为手机上完全失效,因为华为的浏览器对WebRTC支持有阉割。

所以,我的建议是:

如果你只是需要区分内网用户,用后端接口最靠谱。

如果你非要前端独立获取,那就做好降级处理,拿不到就提示用户手动输入,或者用IP归属地接口反查大致位置。

别为了一个IP,把架构搞得过于复杂。

再说说价格,如果你找外包做这个功能,别被坑了。

这种小功能,正常也就几百块搞定,要是有人报价几千,那纯属忽悠。

毕竟逻辑就那点东西,难点在于兼容性和调试。

还有,记得测试不同网络环境。

公司WiFi、家里宽带、手机热点,IP策略都不一样。

特别是手机热点,很多运营商给的是大内网IP,根本没法用来做精确的地理位置判断。

最后提醒一句,别在代码里硬编码IP段。

网络环境千变万化,今天能用的段,明天可能就不行了。

保持代码的灵活性,才是王道。

希望这篇能帮你省下不少调试时间,少走点弯路。

本文关键词:网站开发获取本地ip