获取ip的js原生实现方法
var $ = { getJSON: function(url, params, callbackFuncName, callback){ var paramsUrl ="", jsonp = this.getQueryString(url)[callbackFuncName]; for(var key in params){ paramsUrl+="&"+key+"="+encodeURIComponent(params[key]); } url+=paramsUrl; window[jsonp] = function(data) { window[jsonp] = undefined; try { delete window[jsonp]; } catch(e) {} if (head) { head.removeChild(script); } callback(data); }; var head = document.getElementsByTagName('head')[0]; var script = document.createElement('script'); script.charset = "UTF-8"; script.src = url; head.appendChild(script); return true; }, getQueryString: function(url) { var result = {}, queryString = (url && url.indexOf("?")!=-1 && url.split("?")[1]) || location.search.substring(1), re = /([^&=]+)=([^&]*)/g, m; while (m = re.exec(queryString)) { result[decodeURIComponent(m[1])] = decodeURIComponent(m[2]); } return result; } }; function getIP(callback) { let recode = {}; let RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection; // 如果不存在则使用一个iframe绕过 if (!RTCPeerConnection) { // 因为这里用到了iframe,所以在调用这个方法的script上必须有一个iframe标签 // <iframe id="iframe" sandbox="allow-same-origin" style="display:none;"></iframe> let win = iframe.contentWindow; RTCPeerConnection = win.RTCPeerConnection || win.mozRTCPeerConnection || win.webkitRTCPeerConnection; } //创建实例,生成连接 let pc = new RTCPeerConnection(); // 匹配字符串中符合ip地址的字段 function handleCandidate(candidate) { let ip_regexp = /([0-9]{1,3}(\.[0-9]{1,3}){3}|([a-f0-9]{1,4}((:[a-f0-9]{1,4}){7}|:+[a-f0-9]{1,4}){6}))/; let ip_isMatch = candidate.match(ip_regexp)[1]; if (!recode[ip_isMatch]) { callback(ip_isMatch); recode[ip_isMatch] = true; } } //监听icecandidate事件 pc.onicecandidate = (ice) => { if (ice.candidate) { handleCandidate(ice.candidate.candidate); } }; //建立一个伪数据的通道 pc.createDataChannel(''); pc.createOffer((res) => { pc.setLocalDescription(res); }, () => {}); //延迟,让一切都能完成 setTimeout(() => { let lines = pc.localDescription.sdp.split('\n'); lines.forEach(item => { if (item.indexOf('a=candidate:') === 0) { handleCandidate(item); } }) }, 1000); } //获取外网ip $.getJSON("https://api.ipify.org/?format=jsonp&v="+Math.random()+"&callback=test", null, "callback", function(data){ console.log(data.ip); }); //内网ip getIP( function (ip) { console.log(ip); })
延伸功能:
很多时候,h5需要用到游客模式,又要生成一个唯一的设备id,来记录当前用户的操作。这个时候可以结合Fingerprint2 去处理。由于Fingerprint2 中的很多key值取到的是undefine,会造成大面积重复问题。解决此问题,可以在Fingerprint2获取到的json基础上,添加两个key(即外网ip,内网ip)。然后再对其hash操作,这样得到的数据应该更准确些,也减少了重复。思想和 https://juejin.im/post/5c52d6aae51d453be8018afa 这篇文章类似。但是此文加了一个key,即外网ip。这样wifi情况下还是有问题,所以在这里又补充了内网ip。

浙公网安备 33010602011771号