个性化阅读
专注于IT技术分析

如何仅使用JavaScript获取客户端IP地址

本文概述

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。

玩得开心 !

赞(0)
未经允许不得转载:srcmini » 如何仅使用JavaScript获取客户端IP地址

评论 抢沙发

评论前必须登录!