如何在不联网情况下在前端使用js拿到用户内网IP。。。

问题描述

如何在不联网情况下,使用js拿到客户端内网IP并且支持ie浏览器!

问题出现的环境背景及自己尝试过哪些方法

从网上找了很多方法已经试过了。
1.在Chrome已经使用过webrtc-ips方法,但是不知道是什么原因,还是拿不到,并且该方法不支持ie。
2.解决webrtc-ips拿不到ip的问题时,也使用了webrtc-ips插件,作者本人的demo就不能拿到。。。
3.使用过搜狐,腾讯的ip支持,但是必须联网才能获取到。

相关代码

// 网上唯一的webrtc-ips方法,这个也拿不到ip?

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    </head>
    <body>
        <h4>
            Demo for:
            <a href="https://github.com/diafygi/webrtc-ips">
                https://github.com/diafygi/webrtc-ips
            </a>
        </h4>
        <p>
            This demo secretly makes requests to STUN servers that can log your
            request. These requests do not show up in developer consoles and
            cannot be blocked by browser plugins (AdBlock, Ghostery, etc.).
        </p>
        <h4>Your local IP addresses:</h4>
        <ul></ul>
        <h4>Your public IP addresses:</h4>
        <ul></ul>
        <script>
            //get the IP addresses associated with an account
            function getIPs(callback){
                var ip_dups = {};
                //compatibility for firefox and chrome
                var RTCPeerConnection = window.RTCPeerConnection
                    || window.mozRTCPeerConnection
                    || window.webkitRTCPeerConnection;
                var useWebKit = !!window.webkitRTCPeerConnection;
                //bypass naive webrtc blocking
                if(!RTCPeerConnection){
                    //create an iframe node
                    var iframe = document.createElement('iframe');
                    iframe.style.display = 'none';
                    //invalidate content script
                    iframe.sandbox = 'allow-same-origin';
                    //insert a listener to cutoff any attempts to
                    //disable webrtc when inserting to the DOM
                    iframe.addEventListener("DOMNodeInserted", function(e){
                        e.stopPropagation();
                    }, false);
                    iframe.addEventListener("DOMNodeInsertedIntoDocument", function(e){
                        e.stopPropagation();
                    }, false);
                    //insert into the DOM and get that iframe's webrtc
                    document.body.appendChild(iframe);
                    var win = iframe.contentWindow;
                    RTCPeerConnection = win.RTCPeerConnection
                        || win.mozRTCPeerConnection
                        || win.webkitRTCPeerConnection;
                    useWebKit = !!win.webkitRTCPeerConnection;
                }
                //minimal requirements for data connection
                var mediaConstraints = {
                    optional: [{RtpDataChannels: true}]
                };
                //firefox already has a default stun server in about:config
                //    media.peerconnection.default_iceservers =
                //    [{"url": "stun:stun.services.mozilla.com"}]
                var servers = undefined;
                //add same stun server for chrome
                if(useWebKit)
                    servers = {iceServers: [{urls: "stun:stun.services.mozilla.com"}]};
                //construct a new RTCPeerConnection
                var pc = new RTCPeerConnection(servers, mediaConstraints);
                function handleCandidate(candidate){
                    //match just the IP address
                    var ip_regex = /([0-9]{1,3}(\.[0-9]{1,3}){3})/
                    var ip_addr = ip_regex.exec(candidate)[1];
                    //remove duplicates
                    if(ip_dups[ip_addr] === undefined)
                        callback(ip_addr);
                    ip_dups[ip_addr] = true;
                }
                //listen for candidate events
                pc.onicecandidate = function(ice){
                    //skip non-candidate events
                    if(ice.candidate)
                        handleCandidate(ice.candidate.candidate);
                };
                //create a bogus data channel
                pc.createDataChannel("");
                //create an offer sdp
                pc.createOffer(function(result){
                    //trigger the stun server request
                    pc.setLocalDescription(result, function(){}, function(){});
                }, function(){});
                //wait for a while to let everything done
                setTimeout(function(){
                    //read candidate info from local description
                    var lines = pc.localDescription.sdp.split('\n');
                    lines.forEach(function(line){
                        if(line.indexOf('a=candidate:') === 0)
                            handleCandidate(line);
                    });
                }, 1000);
            }
            //insert IP addresses into the page
            getIPs(function(ip){
                var li = document.createElement("li");
                li.textContent = ip;
                //local IPs
                if (ip.match(/^(192\.168\.|169\.254\.|10\.|172\.(1[6-9]|2\d|3[01]))/))
                    document.getElementsByTagName("ul")[0].appendChild(li);
                //assume the rest are public IPs
                else
                    document.getElementsByTagName("ul")[1].appendChild(li);
            });
        </script>
    </body>
</html>

你期待的结果是什么?实际看到的错误信息又是什么?

上述代码会报错:pc.localDescription.sdp undefined,打印出来pc.localDescription为null。
麻烦各位帮忙看一下。
最后: 如何在不联网情况下在前端使用js拿到用户内网IP,并且支持ie!

阅读 5.4k
3 个回答

有人回答吗???

H5的WebRTC确实能拿到本机所有网络适配器的本地ip(路由器分配的)。

指出几个错误:

  1. 你获取localDescription是通过setTimeout,但你又实现了onicecandidate,其实只需在onicecandidate进行处理即可,当onicecandidate的参数event.candidate==null时,代表所有ip(0-n个)均已拿到,这时候再执行setTimeout里面那坨代码。
  2. 你准备支持IE,这个本身是个错误。现代比IE份额高的浏览器多了去了。
        This demo secretly makes requests to STUN servers that can log your
        request. These requests do not show up in developer consoles and
        cannot be blocked by browser plugins (AdBlock, Ghostery, etc.).

看不懂可以在线翻译

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题