JavaScript 获取客户端IP 以及 外网IP
客户端 ip 也叫做内网 ip、本地 ip。使用 js 获取内网 IP 目前比较有效的方法通过 WebRTC 接口来获取。
通常浏览器没有禁用 WebRTC,在 firefox 以及 chrome 浏览器下都能正常执行。不过该接口并不支持IE,除非在您的系统需要兼容IE,那么您可能就需要通过 ActiveX 来获取 IP了。
外网 ip 也叫做公网 ip、广域网 ip。使用 js 获取外网 ip 使用 搜狐接口 可以轻松获取我们的外网信息。
使用JS 来获取内外网 IP,如下对代码封装一个可用函数。如果您需要使用 WebRTC 接口来获取 本地 IP,引用如下方法即可获取我们需要的客户端 IP 以及 外网 IP。
Define (ip.info.js):
//get the IP addresses associated with an account
export default function getIPs(){
// use this function at callback get intranet ip
this.intranetIP = function(callback) {
try{ // global capture abnormal
var ip_dups = {};
//compatibility for firefox and chrome
var RTCPeerConnection = window.RTCPeerConnection
|| window.mozRTCPeerConnection
|| window.webkitRTCPeerConnection;
var useWebKit = !!window.webkitRTCPeerConnection;
//bypass naive webrtc blocking using an iframe
if(!RTCPeerConnection){
//NOTE: you need to have an iframe in the page right above the script tag
//
//<iframe id="iframe" sandbox="allow-same-origin" style="display: none"></iframe>
//<script>...getIPs called in here...
//
var iframeRTC = document.getElementById("iframe-rtc");
if(!iframeRTC) {
iframeRTC = document.createElement('iframe');
iframeRTC.setAttribute('id','iframe-rtc');
iframeRTC.setAttribute('sandbox','allow-same-origin');
iframeRTC.style.display = 'none';
document.body.appendChild(iframeRTC);
}
var win = iframeRTC.contentWindow;
RTCPeerConnection = win.RTCPeerConnection
|| win.mozRTCPeerConnection
|| win.webkitRTCPeerConnection;
useWebKit = !!win.webkitRTCPeerConnection;
}
//minimal requirements for data connection
var mediaConstraints = {
optional: [{RtpDataChannels: true}]
};
// var servers = {iceServers: [{urls: "stun:stun.services.mozilla.com"}]};
var servers = {iceServers: []};
//construct a new RTCPeerConnection
var pc = new RTCPeerConnection(servers, mediaConstraints);
function handleCandidate(candidate){
//match just the IP address
var ip_regex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/
var ip_addr = ip_regex.exec(candidate)[1];
//remove duplicates
if(ip_dups[ip_addr] === undefined) {
callback(ip_addr);
ip_dups[ip_addr] = true;
}
// console.log(ip_addr);
}
//listen for candidate events
pc.onicecandidate = function(ice){
//skip non-candidate events
if(ice.candidate) {
handleCandidate(ice.candidate.candidate);
}
};
//create a bogus data channel
pc.createDataChannel("");
//create an offer sdp
pc.createOffer(function(result){
//trigger the stun server request
pc.setLocalDescription(result, function(){}, function(){});
}, function(){});
//wait for a while to let everything done
setTimeout(function(){
//read candidate info from local description
var lines = pc.localDescription.sdp.split('\n');
for(var i = 0;i < lines.length;i++) {
if(lines[i].indexOf('a=candidate:') === 0) {
handleCandidate(lines[i]);
}
}
}, 1000);
}catch(e){
//TODO handle the exception
console.log('Init RTCPeerConnection Fail...');
callback("");
}
}
// use this function at callback get extranet ip
this.extranetIp = function(callback) {
try{
var scriptCityjson = document.getElementById("script-cityjson");
if(!scriptCityjson && !window.returnCitySN) {
scriptCityjson = document.createElement('script');
scriptCityjson.setAttribute('src','http://pv.sohu.com/cityjson?ie=utf-8');
document.body.appendChild(scriptCityjson);
var timeSize = 0;
var polling = function() {
setTimeout(function() {
timeSize += 200;
if(window.returnCitySN || timeSize > 3000) {
callback(window.returnCitySN);
}else {
polling();
}
},200)
};
polling();
}else {
callback(window.returnCitySN);
}
}catch(e){
console.log('Init ExtranetIp Script Fail...');
callback("");
}
}
}
Use:
var gi = new getIPs();
// 获取当前客户端IP
gi.intranetIP(function(ip) {
console.log('intranet ip => ' + ip);
});
// 获取当前外网IP
gi.extranetIp(function() {
console.log('extranet ip => ' + ip);
})