2013-11-25 148 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; 
}