因需求需要获取客户端的本机IP,国内资料基本上都是通过向一个IP网站发送请求并获取IP,这样有一定几率泄露自己的IP,在内网环境下也并不适用。
后来在stackoverflow上找到一种解决办法,用WebRTC API直接在本地获取IP,在目前的情境下相对可行,但目前WebRTC只支持Chrome和Firefox、以及Webkit内核的Opera。IE/Edge的兼容似乎需要用Object RTC,后者仍有待商榷。
注:createOffer方法使用Promise方式进行成功后的处理。
function findIP(onNewIP) { // onNewIp - your listener function for new IPs
var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; //compatibility for firefox and chrome
var pc = new myPeerConnection({iceServers: []}), // 空的ICE服务器(STUN或者TURN)
noop = function() {},
localIPs = {}, //记录有没有被调用到onNewIP这个listener上
ipRegex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g,
key; function ipIterate(ip) {
if (!localIPs[ip]) onNewIP(ip);
localIPs[ip] = true;
}
pc.createDataChannel(""); //create a bogus data channel
pc.createOffer().then(function(sdp) {
sdp.sdp.split('\n').forEach(function(line) {
if (line.indexOf('candidate') < 0) return;
line.match(ipRegex).forEach(ipIterate);
});
pc.setLocalDescription(sdp, noop, noop);
}); // create offer and set local description
pc.onicecandidate = function(ice) { //listen for candidate events
if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(ipRegex)) return;
ice.candidate.candidate.match(ipRegex).forEach(ipIterate);
};
} var ul = document.createElement('ul');
ul.textContent = 'Your IPs are: '
document.body.appendChild(ul); function addIP(ip) {
console.log('got ip: ', ip);
var li = document.createElement('li');
li.textContent = ip;
ul.appendChild(li);
} findIP(addIP);