【问题标题】:How to get local/internal IP with JavaScript如何使用 JavaScript 获取本地/内部 IP
【发布时间】:2015-12-26 13:11:50
【问题描述】:

如何使用 WebRTC 获取本地客户端 IP。

我不需要客户端的REMOTE_ADDR,而是他的本地网络IP。 我以前在sharedrop.com 之类的网站上看到过,它使用 WebRTC 识别同一网络中的计算机。

在 PHP 中,我这样做是为了获取客户端远程 IP:

<?php
  echo $_SERVER["REMOTE_ADDR"]; // which would return 72.72.72.175
?>

我查看了stackoverflow,但每个问题都使用远程地址回答。

如何使用 JavaScript 而不是远程地址获取我的本地 IP(例如 192.168.1.24)。

【问题讨论】:

标签: javascript network-programming ip webrtc


【解决方案1】:

更新

不幸的是,以下答案不再有效,因为浏览器出于安全考虑已经改变了这种行为。见this StackOverflow Q&A for more details


我从哪里获取代码 --> Source

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

我已经修改了源代码,减少了行数,没有发出任何 stun 请求,因为您只想要本地 IP 而不是公共 IP,以下代码适用于最新的 Firefox 和 Chrome:

    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){  //listen for candidate events
        if(!ice || !ice.candidate || !ice.candidate.candidate)  return;
        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;
    };
    

这里发生的事情是,我们正在创建一个虚拟对等连接,并且为了让远程对等方与我们联系,我们通常会相互交换 ice 候选者。并且读取冰候选我们可以知道用户的 ip。

【讨论】:

  • 这实际上有安全隐患,因为这允许攻击者找出当前用户的内部 IP 地址
  • 这缺少清理代码以在您完成后关闭此连接。一遍又一遍地调用它最终会抛出
  • 野生动物园怎么样?
  • Chrome 将 WebRTC 默认更改为 mDNS 并破坏了内网。 stackoverflow.com/questions/56755747/…
【解决方案2】:

您可以在现代浏览器上使用此版本(带有Promisesasync / await

// minified onliner, 219b
const ip = await new Promise((s,f,c=new RTCPeerConnection(),k='candidate')=>(c.createDataChannel(''),c.createOffer(o=>c.setLocalDescription(o),f),c.onicecandidate=i=>i&&i[k]&&i[k][k]&&c.close(s(i[k][k].split(' ')[4]))))
// cleaned, 363b
const ip = await new Promise((resolve, reject) => {
  const conn = new RTCPeerConnection()
  conn.createDataChannel('')
  conn.createOffer(offer => conn.setLocalDescription(offer), reject)
  conn.onicecandidate = ice => {
    if (ice && ice.candidate && ice.candidate.candidate) {
      resolve(i.candidate.candidate.split(' ')[4])
      conn.close()
    }
  }
})

【讨论】:

猜你喜欢
  • 2015-09-12
  • 1970-01-01
  • 2011-03-17
  • 1970-01-01
  • 2015-07-09
  • 2011-08-12
  • 2010-11-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多