好吧,这个面试题属实问到我了,查阅相关资料后,前端获取ip就两种
- 调用接口后端返回ip (兼容性好)
- 使用RTCPeerConnection (不需要任何后端)
方案1 调用接口
获取ip的接口很多,也可以自己做一个,这里我使用api.ipify.org/?format=jso…
fetch('https://api.ipify.org?format=json')
.then(res=>JSON.parse(res).ip)
.then(console.log)
方案2 RTCPeerConnection
这个玩意是用来创建点对点连接的。可以在连接监听中得到连接对象的ip信息。
因为只是获取ip,我们可以使用任意的stun服务器,就算这个服务器不存在,也是可以获取ip的
//创建连接对象
let servers = { iceServers: [{ urls: "stun:localhost" }] };
let pc = new RTCPeerConnection(servers);
//错误回调和成功回调
let errfunc = new Function();
let successfunc = result => pc.setLocalDescription(result);
//创建传输信道
pc.createDataChannel("");
//创建sdp对象
pc.createOffer(successfunc, errfunc);
// 在监听中得到ip地址
pc.onicecandidate = function (ice) {
if(ice.candidate == null) return;
else document.write(ice.candidate.address);
}
运行结果直接看不懂:
06fc1de3-83bc-4944-959d-68572eb0f131.local
这是由于ip地址是非常敏感的信息,一般浏览器设置中默认使用匿名ip地址。 可以在浏览器设置中把匿名ip功能禁用掉,一般这个设置在实验性功能里。
- chrome浏览器进入
chrome://flags/ - edge进入
edge://flags/ - 火狐
about:config
搜索rtc第一个就是。设置成disabled之后需要重启浏览器
重启后刷新一下页面就能看到ip地址了
使用WebRTC获取ip的兼容性不是很好,而且还需要改一下浏览器设置再重启服务器。 手机上只测试了qq浏览器,via浏览器,以及微信内置浏览器,都是可以直接获取到真实ip的