2013-11-25 101 views
49

我知道对这个问题的最初反应是“不”,“不能完成”和“你不应该需要它,你做错了什么”。我想要做的是获取用户的局域网IP地址,并将其显示在网页上。为什么?因为这就是我正在处理的页面的全部内容,尽可能多地显示关于你的信息,访问者: http://www.whatsmyip.org/more-info-about-you/您可以通过JavaScript获取用户本地局域网IP地址吗?

因此,我实际上并没有对IP进行任何操作,除了将它显示给用户出于信息目的。我曾经通过使用一个小的Java小程序来做到这一点。它工作得很好。但是现在,浏览器让你打了很多次的同意和信任,甚至运行最小的java小程序,我宁愿不运行它。

所以有一段时间我刚刚摆脱了这个功能,但如果可能的话我想回来。这是我作为一名计算机顾问实际上会时常使用的东西。进入本网站查看网络运行的IP范围要比进入“系统偏好设置”,“网络”以及任何活动接口更快。

所以我想知道,希望如果有一种方法可以单独使用JavaScript吗?也许你可以访问一些新的对象,类似于JavaScript可以询问浏览器地理位置的地方。也许客户端网络信息有类似之处?如果不是,也许还有其他方式完全可以做到这一点?我能想到的唯一方法是Java小程序或Flash对象。我宁愿不做那些。

+1

你知道答案。为什么问那么? Java小程序或flash对象不太可能被用户所允许(可能只有那些在互联网上是新手的人) - 所以这不是一种常见的解决方案。 ActiveX和附近的东西只在IE中工作 - 因此,其他浏览器的用户不会受到影响(甚至在IE中也有一个安全策略可以防止网站做坏事) –

+0

我的IP地址是通过'HTTP_X_FORWARDED_FOR'在该页面捕获,只是说'。 – tomdemuyt

+15

为什么要问?因为也许,也许,我什么都不知道。 – l008com

回答

64

事实证明,HTML5最近的WebRTC扩展允许javascript查询本地客户端IP地址。概念验证可在此处获得:http://net.ipcalf.com

此功能显然是by design,而不是一个错误。然而,鉴于其具有争议性,我会谨慎依赖这种行为。尽管如此,我认为它完美并恰当地解决了您的预期目的(向用户透露他们的浏览器泄漏的内容)。

+0

这很有帮助。再次感谢! –

+2

它只是在铬和Firefox上工作,而不是在IE,Edge或Safari – ali

43

除了旅途的回答,此代码适用于支持WebRTC(Chrome和Firefox)的浏览器。我听说有一项运动开始实施一项功能,该功能可以让网站请求IP(例如用户的地理位置或用户媒体),尽管这些功能尚未在任何浏览器中实现。

这里是source code的修改版本,减少了线,不作任何STUN请求,因为你只需要本地IP不是公网IP:

window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;//compatibility for Firefox and chrome 
var pc = new RTCPeerConnection({iceServers:[]}), noop = function(){};  
pc.createDataChannel('');//create a bogus data channel 
pc.createOffer(pc.setLocalDescription.bind(pc), noop);// create offer and set local description 
pc.onicecandidate = function(ice) 
{ 
if (ice && ice.candidate && ice.candidate.candidate) 
{ 
    var myIP = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/.exec(ice.candidate.candidate)[1]; 
    console.log('my IP: ', myIP); 
    pc.onicecandidate = noop; 
} 
}; 

我们正在创建远程虚拟对等连接同行与我们联系。我们通常会互相交换冰候选人,并阅读冰上候选人,我们可以告诉用户的IP。

你可以找到一个演示 - >Demo

+0

它在Edge中不起作用。你能解释为什么吗? – dampee

+0

感谢您的Mido!非常感激。 –

+0

@dampee - 我相信Edge目前不支持数据通道。 – MichaelB76

1

你可以找到什么限制的浏览器可能会增加,以减轻这一点,更多的信息是什么IETF正在做这件事,以及为什么需要在IETF SPEC on IP handling

3
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); 
    }; 
} 
+0

请使用编辑器选项适当地设置代码的格式。 – 31piy

+0

如果你不仅仅删除一些代码,而且还会解释他和你的代码中发生了什么,那将会很棒。它可以帮助问题作者和其他用户。这很好,如果它有效,但知道为什么在我看来更重要。 – davejal

0

我清理了mido的帖子,然后清理了他们找到的功能。这将返回falsearray。当测试记得你需要在Web开发者控制台中折叠数组,否则它是非直观的默认行为可能会欺骗你,以为它返回一个空的array

function ip_local() 
{ 
var ip = false; 
window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection || false; 

if (window.RTCPeerConnection) 
{ 
    var ip = []; 
    var pc = new RTCPeerConnection({iceServers:[]}), noop = function(){}; 
    pc.createDataChannel(''); 
    pc.createOffer(pc.setLocalDescription.bind(pc), noop); 

    pc.onicecandidate = function(event) 
    { 
    if (event && event.candidate && event.candidate.candidate) 
    { 
    var s = event.candidate.candidate.split('\n'); 
    ip.push(s[0].split(' ')[4]); 
    } 
    } 
} 

return ip; 
}