Vue實戰041:獲取當前客戶端IP地址詳解(內網和外網)


前言

我們經常會有需求,希望能獲取的到當前用戶的IP地址,而IP又分為公網ip(也稱外網)和私網IP(也稱內網IP),IP地址是IP協議提供的一種統一的地址格式,每台設備都設定了一個唯一的IP地址”,從而確保了用戶在連網的計算機上操作時,能夠快速地從互聯網中找到自己所需的對象。

Vue實戰041:獲取當前客戶端IP地址詳解(內網和外網)

 

外網IP和內網IP的區別

1,外網IP是全球唯一的IP地址,僅分配給某一台網絡設備。內網IP是由路由器分配給每一台設備內部使用的IP地址;

2,外網IP任何一台設備都可以ping通。內網IP只有在同一環境的內部設備才能ping通;

3,外網用戶無法直接訪問到內網用戶,內網用戶可以訪問外網用戶,因為內網的所有用戶都是通過同一個外網IP進行上網的;

如何獲取外網IP

這里我們可以借助現成的接口,搜狐提供的一個JS接口獲取IP地址,我們只需在入口index.html中直接引入該接口即可輕松獲取到當前用戶的外網ip,Vue中在public中的index.html中引入接口,然后再需要獲取的地方通過returnCitySN['cip']即可拿到IP地址,然后將IP存到localstorage或者Vuex中,這樣隨時可以調用了。

//引入JS
<script src="http://pv.sohu.com/cityjson?ie=utf-8"></script>
//在組件中獲取,可以選擇在首頁載入前獲取該參數
var Ip=returnCitySN['cip']
localStorage.setItem('Ip', Ip)

如何獲取內網IP

獲取內網IP相對來說會復雜些,畢竟沒有現成的接口可以調用,這里我們用到了WebRTC(網頁即時通信),在WebRTC規范中,RTCPeerConnection可以用於視頻流/音頻流、以及數據的傳輸。這里們通過RTCPeerConnection 對象建立一個連接通道,下面3個或對象是針對不同瀏覽器來創建的。

var RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection;

當RTCPeerConnection對象存在時,我們就可以實例化該對象並創建一個可以發送任意數據的數據通道,此時我們的RTCPeerConnection對象中數據基本都是null。

var RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
if (RTCPeerConnection) (()=>{
var rtc = new RTCPeerConnection()
rtc.createDataChannel(''); //創建一個可以發送任意數據的數據通道
})()
Vue實戰041:獲取當前客戶端IP地址詳解(內網和外網)

 

什么是SDP

SDP 是一種會話描述格式 ,由許多文本行組成,文本行的格式為<類型>=<值>,<類型>是一個字母,<值>是結構化的文本串。SDP中包含了很多媒體信息,包括了媒體類型(video)、傳輸協議(RTP/UDP/IP)、媒體格式(H.264 video)、多播或單播地址和端口、本端的帶寬信息、本端的加密信息等。

Vue實戰041:獲取當前客戶端IP地址詳解(內網和外網)

 

建立sdp數據

我們從要做的就是從SDP中拿到傳輸協議中的信息,創建一條sdp數據並將數據存入LocalDescription對象中。這樣我們在LocalDescription中就得到了所有的SDP數據,從下圖中我們可以看到有IP地址在里面,接下來就可以從sdq中提取ip地址了。

rtc.createOffer( offerDesc => { //創建並存儲一條sdp數據
rtc.setLocalDescription(offerDesc)
}, e => { console.warn(e)})
Vue實戰041:獲取當前客戶端IP地址詳解(內網和外網)

 

監聽candidate事件

onicecandidate屬性在RTCPeerConnection實例上發生icecandidate事件時要調用的函數,當我們向服務器發送消息時觸發並獲取到SDP中的candidate屬性,而candidate中正好有我們想要的IP地址,你可以直接獲取var ip_addr = evt.candidate.address。當然你也可以從candidate屬性中獲取,不過這里就會復雜點,用個正則來提取吧(顯然方法一簡單)。

 rtc.onicecandidate =(evt) => { //監聽candidate事件
if (evt.candidate) {
//方法一:
var ip_addr = evt.candidate.address
//方法二:
let ip_rule = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/.
var ip_addr = ip_rule.exec(evt.candidate.candidate)[1]
console.log("ip_addr==",ip_addr)
}}
Vue實戰041:獲取當前客戶端IP地址詳解(內網和外網)

 

代碼封裝

最后整理下代碼,封裝成一個方法需要的時候直接調用即可,通過localStorage來存儲獲取到的ip_addr(或者Vuex存儲),然后我們只需要通過localStorage.getItem('ip_addr'))就可以獲取到我們的內網IP地址了。

getUserIP(){
var RTCPeerConnection = window.RTCPeerConnection || window.webkitRTCPeerConnection || window.mozRTCPeerConnection;
if (RTCPeerConnection) (()=>{
var rtc = new RTCPeerConnection()
rtc.createDataChannel(''); //創建一個可以發送任意數據的數據通道
rtc.createOffer( offerDesc => { //創建並存儲一個sdp數據
rtc.setLocalDescription(offerDesc)
}, e => { console.log(e)})
rtc.onicecandidate =(evt) => { //監聽candidate事件
if (evt.candidate) {
var ip_addr = evt.candidate.address
localStorage.setItem('ip_addr',ip_addr)
}}
})()
else{console.log("目前僅測試了chrome瀏覽器OK")}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM