前端开发时,有些需求,需要得到访问客户的ip地址,大多时候靠后端完成,但其实前端也可以拿到,例如下面三种:
第一种:用于仅支持IE的且允许Activex运行,利用ActiveObject来获取。
第二种:利用其它平台的接口,在自己程序中使用如:新浪,搜狐、太平洋等的接口,来给用户返回ip地址
<script type="text/javascript" src="http://pv.sohu.com/cityjson?ie=utf-8"></script>
<script>
// 公网ip地址
console.log(returnCitySN["cip"])
</script>
第三种:使用WebRTC(Web Real-Time Communications),他的定义是一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和(或)音频流或者其他任意数据的传输。这些信息和基本api在MDN上面是可以查看的。我们可以使用WebRTC获取ip地址,经测试,在chrome,opera,firefox,safari均可正常获取,对于IE和Edge,可以采用第一种方式进行兼容。下面是获取代码(这里没有支持IE/Edge):
如果使用 chrome 浏览器打开,此时可能会看到一串类似于:`e87e041d-15e1-4662-adad-7a6601fca9fb.local 的机器码,这是因为chrome 默认是隐藏掉 内网IP地址的,可以通过修改 chrome 浏览器的配置更改此行为:
在chrome 浏览器地址栏中输入:chrome://flags/
搜索#enable-webrtc-hide-local-ips-with-mdns 该配置 并将属性改为 disabled
// 内网ip地址
var RTCPeerConnection =window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
if (RTCPeerConnection) (function () {
var rtc = new RTCPeerConnection({iceServers:[]});
if (1 || window.mozRTCPeerConnection) {
rtc.createDataChannel('', {reliable:false});
};
rtc.onicecandidate = function (evt) {
// convert the candidate to SDP so we can run it through our general parser
// see https://twitter.com/lancestout/status/525796175425720320 for details
if (evt.candidate) grepSDP("a="+evt.candidate.candidate);
};
rtc.createOffer(function (offerDesc) {
grepSDP(offerDesc.sdp);
rtc.setLocalDescription(offerDesc);
}, function (e) { console.warn("offer failed", e); });
var addrs = Object.create(null);
addrs["0.0.0.0"] = false;
function updateDisplay(newAddr) {
if (newAddr in addrs) return;
else addrs[newAddr] = true;
var displayAddrs = Object.keys(addrs).filter(function (k) { return addrs[k]; });
document.getElementById('list').textContent = displayAddrs.join(" or perhaps ") || "n/a";
}
function grepSDP(sdp) {
var hosts = [];
sdp.split('\r\n').forEach(function (line) {
if (~line.indexOf("a=candidate")) {
var parts = line.split(' '),
addr = parts[4],
type = parts[7];
if (type === 'host') updateDisplay(addr);
} else if (~line.indexOf("c=")) {
var parts = line.split(' '),
addr = parts[2];
updateDisplay(addr);
}
});
}
})(); else {
document.getElementById('list').innerHTML = "<code>ifconfig | grep inet | grep -v inet6 | cut -d\" \" -f2 | tail -n1</code>";
document.getElementById('list').nextSibling.textContent = "In Chrome and Firefox your IP should display automatically, by the power of WebRTCskull.";
}
获取浏览器信息:使用包含浏览器信息的Navigator对象,这个对象虽然没有公开标准,但是所有的浏览器都支持他,主要用到的是useragent属性,它包含了这些信息,我们要做的只是使用正则表达式分离和提取,针对不同的浏览器,兼容chrome,firefox,opera,ie,edge,safari等,对于其他浏览器,例如360极速等,会返回相应内核对应的浏览器名称。也可以再进行其他判断。下面是代码:
function getBrowserInfo(){
var agent = navigator.userAgent.toLowerCase() ;
console.log(agent);
var arr = [];
var system = agent.split(' ')[1].split(' ')[0].split('(')[1];
arr.push(system);
var regStr_edge = /edge\/[\d.]+/gi;
var regStr_ie = /trident\/[\d.]+/gi ;
var regStr_ff = /firefox\/[\d.]+/gi;
var regStr_chrome = /chrome\/[\d.]+/gi ;
var regStr_saf = /safari\/[\d.]+/gi ;
var regStr_opera = /opr\/[\d.]+/gi;
//IE
if(agent.indexOf("trident") > 0){
arr.push(agent.match(regStr_ie)[0].split('/')[0]);
arr.push(agent.match(regStr_ie)[0].split('/')[1]);
return arr;
}
//Edge
if(agent.indexOf('edge') > 0){
arr.push(agent.match(regStr_edge)[0].split('/')[0]);
arr.push(agent.match(regStr_edge)[0].split('/')[1]);
return arr;
}
//firefox
if(agent.indexOf("firefox") > 0){
arr.push(agent.match(regStr_ff)[0].split('/')[0]);
arr.push(agent.match(regStr_ff)[0].split('/')[1]);
return arr;
}
//Opera
if(agent.indexOf("opr")>0){
arr.push(agent.match(regStr_opera)[0].split('/')[0]);
arr.push(agent.match(regStr_opera)[0].split('/')[1]);
return arr;
}
//Safari
if(agent.indexOf("safari") > 0 && agent.indexOf("chrome") < 0){
arr.push(agent.match(regStr_saf)[0].split('/')[0]);
arr.push(agent.match(regStr_saf)[0].split('/')[1]);
return arr;
}
//Chrome
if(agent.indexOf("chrome") > 0){
arr.push(agent.match(regStr_chrome)[0].split('/')[0]);
arr.push(agent.match(regStr_chrome)[0].split('/')[1]);
return arr;
}else{
arr.push('请更换主流浏览器,例如chrome,firefox,opera,safari,IE,Edge!')
return arr;
}
}