Firefox 跟 Chrome支持WebRTC可以向STUN服务器请求,返回内外网IP,不同于XMLHttpRequest请求,STUN请求开发者工具当中看不到网络请求的。( [* [' A& u( E. L. G. t0 I, I' d
2 ], H. W& v; S/ }5 p//get the IP addresses associated with an account
% E/ n0 f8 U4 w3 d& rfunction getIPs(callback){
: \ H' T( i; u/ v var ip_dups = {};- }1 P1 h5 e. Z8 x$ d
' P# \7 C$ w# `
//compatibility for firefox and chrome/ k' h( l1 `4 P0 Y1 E% w
var RTCPeerConnection = window.RTCPeerConnection
, I/ N- w, |2 s' N N4 u! o || window.mozRTCPeerConnection
$ \$ g! W! G: b L0 D || window.webkitRTCPeerConnection;
1 V! _6 ?. t, [; p: J: p# h r var mediaConstraints = {4 [+ c* ]) a7 u6 e8 K2 {3 p
optional: [{RtpDataChannels: true}]
" ?4 u7 d0 ^! m7 P };4 X4 `$ T9 U- q1 Y3 ?; y: q4 d/ \5 t
) o: ~0 [; {; n+ k4 c9 |/ V //firefox already has a default stun server in about:config7 f1 J; J( F$ o+ [% a. A
// media.peerconnection.default_iceservers =
, e3 V; p( _" d8 G& d7 t. i6 u // [{"url": "stun:stun.services.mozilla.com"}]
+ D8 x; T2 A. H8 s, o! j var servers = undefined;
: \! d' O( S* o, A& D . M& G6 m3 n) {8 w% r- w" S
//add same stun server for chrome9 x3 z3 B' z- a! Q8 U' R; u7 c @
if(window.webkitRTCPeerConnection)
; s, g8 K; z* A. g- T servers = {iceServers: [{urls: "stun:stun.services.mozilla.com"}]};
) k) w- B: E8 o4 Y2 J! t! S7 l % c$ j' w! y" P, ?) j1 s) v
//construct a new RTCPeerConnection& e, y6 M. y+ f0 F+ B: x
var pc = new RTCPeerConnection(servers, mediaConstraints);
7 v, t- u4 J$ X4 c3 M
1 |4 X4 c" k3 D1 _. Q* O/ h //listen for candidate events
, `4 z" K; N' B% b* y2 s( R pc.onicecandidate = function(ice){8 X; D3 e) M Y* ~1 @. L1 ^
; C0 Y( ^7 d6 T! C: h //skip non-candidate events* X$ h- X% a# l& S* ?6 |+ t
if(ice.candidate){2 T* G$ A) a7 h- e1 x9 L0 u
0 h6 `/ ]/ R& e' P- B+ ~1 t, _
//match just the IP address
0 b S. F$ }' u2 s+ ? M7 `0 ~ var ip_regex = /([0-9]{1,3}(\.[0-9]{1,3}){3})/& U" E% g* g" z% `& o
var ip_addr = ip_regex.exec(ice.candidate.candidate)[1];$ `! o' ^7 j- h, R6 c
* w5 S3 _! p$ E" r& |; M | //remove duplicates
: ~; J, u {9 i% C9 C if(ip_dups[ip_addr] === undefined)( U# R6 k. D/ u5 ]# t5 @
callback(ip_addr);
" e9 d* C. ~& `- J $ w) A7 m; g, ^/ ]5 E
ip_dups[ip_addr] = true;2 R* Q. x$ j7 u. C4 r! s q- p2 W
}
4 u9 T) Y6 O' ^; q9 y- G: Z* x };
4 o8 a7 P, g7 q. I/ l% A- G 5 w, V; p, p% N) o/ O! p
//create a bogus data channel
# v7 a; |- ]1 Q* M pc.createDataChannel("");. T2 i L5 Z2 y5 I- V4 ?
: k0 A+ I8 ?; N% m0 g //create an offer sdp
- t% L! }1 Z5 S4 ~8 h pc.createOffer(function(result){
9 i. J+ H; `8 c- _
( D1 w1 K4 P* ?# k8 e" K1 y //trigger the stun server request6 B( M: B' o; \4 t
pc.setLocalDescription(result, function(){});
8 X2 N; i3 d' J/ G* B 7 ?1 T* v, g" ]+ h
}, function(){});
* o3 f# a, l: `! B3 k8 n! ]}
1 {% Z6 X! d7 ^, x+ G6 r ]% r
- |& [+ r- t, Y# h0 Y- T//Test: Print the IP addresses into the console& B- R& L' \) `% Z) I* C E3 d1 T
getIPs(function(ip){console.log(ip);}); |
|