本文概述
Javascript无法获取(也不能在某个位置存储)客户端IP, 但是Javascript能够创建Http请求, 并且服务器端语言能够检索用户公共IP, 因此你可以利用此优势。换句话说, 如果你要检索用户的公共IP, 则必须从请求到任何服务器的依赖才能检索IP。但是, 随着WebRTC的引入, 你将能够使用RTCPeerConnection技巧性地检索用户的私有IP。
在本文中, 你将学习如何通过一些技巧轻松地检索用户IP(使用纯JavaScript的私有IP和使用第三方服务的公共IP)。
使用webRTC(获取专用IP)
RTCPeerConnection接口允许你在计算机和远程对等方之间创建WebRTC连接。但是, 我们将为其创建”中断”版本, 以便仅使用javascript检索客户端的IP。
createOffer方法启动会话描述协议(SDP)的创建, 该会话描述协议提供有关附加到WebRTC会话的任何MediaStreamTrack, 会话, 代码以及ICE代理已经收集的任何候选者的信息(其中包含我们的目标IP)。
在旧版本中, 此方法使用回调。但是, 现在返回一个基于Promise的值, 该值将在填充后返回我们需要的信息:
注意:纯JavaScript实现将返回客户端私有IP, 而不是公共IP。
/**
* Get the user IP throught the webkitRTCPeerConnection
* @param onNewIP {Function} listener function to expose the IP locally
* @return undefined
*/
function getUserIP(onNewIP) { // onNewIp - your listener function for new IPs
//compatibility for firefox and chrome
var myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
var pc = new myPeerConnection({
iceServers: []
}), noop = function() {}, localIPs = {}, ipRegex = /([0-9]{1, 3}(\.[0-9]{1, 3}){3}|[a-f0-9]{1, 4}(:[a-f0-9]{1, 4}){7})/g, key;
function iterateIP(ip) {
if (!localIPs[ip]) onNewIP(ip);
localIPs[ip] = true;
}
//create a bogus data channel
pc.createDataChannel("");
// create offer and set local description
pc.createOffer().then(function(sdp) {
sdp.sdp.split('\n').forEach(function(line) {
if (line.indexOf('candidate') < 0) return;
line.match(ipRegex).forEach(iterateIP);
});
pc.setLocalDescription(sdp, noop, noop);
}).catch(function(reason) {
// An error occurred, so handle the failure to connect
});
//listen for candidate events
pc.onicecandidate = function(ice) {
if (!ice || !ice.candidate || !ice.candidate.candidate || !ice.candidate.candidate.match(ipRegex)) return;
ice.candidate.candidate.match(ipRegex).forEach(iterateIP);
};
}
// Usage
getUserIP(function(ip){
alert("Got IP! :" + ip);
});
getUserIP方法期望在客户端IP可用时将调用的函数作为第一个参数。回调接收一个字符串(ip)作为第一个(也是唯一的)参数。你可以通过JSFiddle查看运行中的上一片段:
使用第三方服务(获取公共IP)
如果你需要提供跨浏览器支持, 则将无法使用RTCPeerConnection来检索客户端专用IP, 因此, 你拥有的唯一资源是外部服务(对服务器, 第三方服务或你的请求的请求)你自己的服务器中的自动实现的服务)。
不安全的连接HTTP
要从没有SSL证书的网站获取用户的IP, 可以依靠ipinfo.io。该服务提供了一个API, 可通过简单的ajax调用获取客户端IP:
$.getJSON('http://ipinfo.io', function(data){
console.log(data);
});
检索到的数据对象包含可用的本地化信息, 例如:国家/地区, 城市等。 ipinfo的服务器使用基于延迟的DNS路由来尽可能快地处理请求。在此处了解有关ipinfo的更多信息。
安全连接HTTPS(推荐)
为了即使在具有SSL的安全网站中也可以从网站获取用户的IP, 你可以使用ipify服务, 该服务提供了友好的API, 可以轻松获取用户IP。该服务没有请求限制。
你可以在项目中使用它来请求API(如果需要, 可以使用format参数), 然后就可以开始使用了。
API URI | 回应类型 | Sample Output (IPv4) | Sample Output (IPv6) |
https://api.ipify.org | 文本 | 11.111.111.111 | ? |
https://api.ipify.org?format=json | JSON | {” ip”:” 11.111.111.111″} | ? |
https://api.ipify.org?format=jsonp | jsonp | callback({” ip”:” 11.111.111.111″}); | ? |
https://api.ipify.org?format=jsonp&callback=getip | jsonp | getip({” ip”:” 11.111.111.111″}); | ? |
你可以将其与JSONP一起使用:
<script type="application/javascript">
function getIP(json) {
document.write("My public IP address is: ", json.ip);
}
</script>
<script type="application/javascript" src="https://api.ipify.org?format=jsonp&callback=getIP"></script>
或使用jQuery使用json请求检索对象:
$.getJSON('https://api.ipify.org?format=json', function(data){
console.log(data.ip);
});
此外, 如果你拥有自己的服务器并且能够使用它, 则可以创建自己的私有服务, 该私有服务使用诸如PHP, ASP.NET等服务器语言返回用户的IP。
玩得开心 !
评论前必须登录!
注册