Get the client IP address with Javascript on Safar

2019-08-18 22:16发布

问题:

since Safari updated to version 11 we can use WebRTC API. However, I'm trying to get the client IP address (local IP, i.e. 192.168.1.10) but there is no result.

The code I'm using is the one you can find in several guides. The same code works on Chrome and Firefox, which are compatibles with this API before than Safari. It's something like this:

 /**
 * 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);
});

I've been debugging and I figured out that ice.candidate is not defined, so there isn't any IP to iterate in code.

Any idea or alternative?

Thank you.

回答1:

Safari is implementing the latest version of the spec which, for security reasons, prevent local candidates for being generated. You have an option in the browser that allow you to give safari the permission to do it, but it needs to be done manually. Other browsers are not fully compliant yet and still allow local candidates to be generated.

In the developper menu you can chose to stop filtering the candidates. https://i1.wp.com/webrtcbydralex.com/wp-content/uploads/2017/06/Screen-Shot-2017-06-16-at-3.20.30-PM.png