一台电脑需要两个 ip 才可以上网,一个是本地的内网ip(本地 ip),另一个就是外网 ip(公网 ip)。值得说明的是:外网 ip 具有世界范围的唯一性,而内网 ip 只在局域网内部具有唯一性。并且一个局域网里所有电脑的内网 IP 是互不相同的,但共用一个外网 IP。
获取公网 IP
如果要获取外网公共 ip 地址,则将无法使用 RTCPeerConnection 了,需要借助第三方的服务。
1、使用第三方接口(搜狐)获取公网 ip
<script src="http://pv.sohu.com/cityjson?ie=utf-8"></script>
<script>
// var returnCitySN = {"cip": "220.249.114.149", "cid": "420100", "cname": "湖北省武汉市"};
console.log(returnCitySN["cip"]+','+returnCitySN["cname"])
</script>
还有其他的第三方网址
API URI | Response Type | Sample Output (IPv4) |
---|---|---|
https://api.ipify.org | text | 11.111.111.111 |
https://api.ipify.org?format=json | json | {“ip”:”11.111.111.111”} |
https://api.ipify.org?format=jsonp | jsonp | callback({“ip”:”11.111.111.111”}) |
https://api.ipify.org?format=jsonp\&callback=getip | jsonp | getip({“ip”:”11.111.111.111”}); |
可以使用 jsonp 形式在页面上。
<script type="application/javascript">
function getIP(json) {
document.write("My public IP address is: ", json.ip);
}
</script>
<script type="application/javascript" src="https://api.ipify.org?format=jsonp&callback=getIP"></script>
缺点:
- 依赖接口稳定性
- 有的接口(比如 sohu),不支持国外访问
获取内网 IP
Firefox 和 Chrome 内建的 WebRTC 允许向 STUN 服务器查询用户的本地和公共 IP 地址。查询结果对 javascript 可用,所以可以使用 javascript 得到用户的本地和公网地址。
但是需要特别注意的是需要打开浏览器的响应配置才可以获取到,操作见下图
/**
* Get the user IP throught the webkitRTCPeerConnection
* @param onNewIP {Function} listener function to expose the IP locally
* @return undefined
*/
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);
};
}
// Usage
getUserIP(function (ip) {
alert("Got IP! :" + ip);
});
缺点:
- 只能获取内网 ip
- 只支持 https 或者本地文件的方式访问
- 需要自行设置浏览器配置