因需求需要获取客户端的本机IP,国内资料基本上都是通过向一个IP网站发送请求并获取IP,这样有一定几率泄露自己的IP,在内网环境下也并不适用。
后来在stackoverflow上找到一种解决办法,用WebRTC API直接在本地获取IP,在目前的情境下相对可行,但目前WebRTC只支持Chrome和Firefox、以及Webkit内核的Opera。IE/Edge的兼容似乎需要用Object RTC,后者仍有待商榷。
注:createOffer方法使用Promise方式进行成功后的处理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
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);
|