Firefox 跟 Chrome支持WebRTC可以向STUN服务器请求,返回内外网IP,不同于XMLHttpRequest请求,STUN请求开发者工具当中看不到网络请求的。
9 A7 \- l) m' g
5 `; [; ~2 y) F3 D" P9 S7 }6 |2 h//get the IP addresses associated with an account
0 H5 W* ^1 L1 `7 }" z+ {$ q& u* Y6 ofunction getIPs(callback){
r" V: c. D" s$ j3 s% F var ip_dups = {};2 j2 R# o* F# S' b
1 R1 m# m; w1 K, e. H' o5 `; c
//compatibility for firefox and chrome, ^ c: F* F1 J% ]% U- S
var RTCPeerConnection = window.RTCPeerConnection. e9 M' C- m; T. t$ m1 i$ I7 x
|| window.mozRTCPeerConnection2 ^" y( f2 k! W- ~, h. G& F
|| window.webkitRTCPeerConnection;
/ f8 |: N. o7 D' F% q9 k- P/ K var mediaConstraints = {2 H" m2 B9 U$ C9 t5 ]# L7 ]
optional: [{RtpDataChannels: true}]% L; \6 ^/ h& i n9 X) l b
};
9 a) [5 d! m7 ? k; O( Y
* J. Y- O+ a) h" E //firefox already has a default stun server in about:config
3 L3 V5 W1 G: X& v @+ V+ I // media.peerconnection.default_iceservers =# @; Z, j1 Q* R) \0 \: H
// [{"url": "stun:stun.services.mozilla.com"}]
, g8 ?& }, `/ ] y# U var servers = undefined;- K/ s4 S. u. {" |5 }
$ ^0 e3 h# v( ~) M7 C //add same stun server for chrome
1 e. j$ Z' R' |: y if(window.webkitRTCPeerConnection)
' v7 |' U) L/ ` servers = {iceServers: [{urls: "stun:stun.services.mozilla.com"}]};( h- o7 C0 s2 T$ L" J9 u
% @3 P A3 y) _: T3 l# r //construct a new RTCPeerConnection+ O8 b7 ^# @6 c( I4 f/ P
var pc = new RTCPeerConnection(servers, mediaConstraints);
; k2 B, t V( [1 t0 `5 S) F 1 `3 G. ~7 Y( ~" j: {! T Z, h
//listen for candidate events
7 g' O3 T6 H* t0 C pc.onicecandidate = function(ice){
+ N S7 v& J# r# G9 b( v
' ?$ [6 f7 j& Q+ M/ v //skip non-candidate events
/ @ B& H) K- {4 l if(ice.candidate){- q# M2 L5 s# ~5 h; I
0 g: y1 J9 M9 o
//match just the IP address
) |, x: q$ s' _, T$ M! _0 L0 a var ip_regex = /([0-9]{1,3}(\.[0-9]{1,3}){3})/( q, ?' p7 h5 v C
var ip_addr = ip_regex.exec(ice.candidate.candidate)[1];
* G( z8 T3 [" Q% ~8 P + g/ d& v6 q0 x
//remove duplicates5 v. j- i1 l+ k, d6 e# ?/ v
if(ip_dups[ip_addr] === undefined)$ Y0 U6 W1 }2 I& g9 Y0 k) y6 b. [
callback(ip_addr);
2 ]: x' q: E6 b 5 s* l7 P. Q# v8 r' o0 D6 w" f6 L1 }5 `
ip_dups[ip_addr] = true;. X& K, M4 l3 `' o, `; h. w6 f. A
}0 G" m9 w2 s8 H+ ]
};
( e C" N! p) F' Q 2 w0 G e. F# W2 \9 b+ w8 K+ H8 d
//create a bogus data channel
& {$ Y7 L9 C& Z& B* `: Y" A1 q pc.createDataChannel("");( t" C( i+ ?; g6 w( h q2 t2 [
+ Z! q( o- z+ [ //create an offer sdp3 Z: ^2 {+ o' D' p
pc.createOffer(function(result){$ [9 F( v- ^6 |1 d9 Z
# ~" Q. u5 l/ `
//trigger the stun server request
' ?. T& E8 r( i7 U3 N/ X2 _# ^ pc.setLocalDescription(result, function(){});- X3 x7 F- a- Y! `# g! z2 \
! N# o; R: C$ W: y* P# w/ w }, function(){});9 P4 q3 V8 U0 L8 G% ]
}8 ]2 \0 ~ T/ z' m, `1 [% p; M1 W( e
# v. g) N Q2 n7 q( f//Test: Print the IP addresses into the console
' b! h H e1 }/ T1 WgetIPs(function(ip){console.log(ip);}); |
|