获取IP地址
前端获取途径
1. 通过webRTC
的方式获取
这种方式需要浏览器支持webRTC
对象或没有屏蔽webRTC
。所以可能部分用户无法使用好处在于可以自控
参考链接:
// 自执行函数,返回一个函数。
var init = function () {
var Rpc, rpcInstance, sdp, obj = {}
var ipArr = []
var ready = new ReadyObj()
// 定时器,每10ms执行一次
var intervalTimer = setInterval(function () {
if (rpcInstance && rpcInstance.localDescription && rpcInstance.localDescription.sdp && sdp != rpcInstance.localDescription.sdp) {
sdp = rpcInstance.localDescription.sdp
handleSdp(sdp)
}
}, 10)
function chargeReady() {
if (!ready.isReady()) {
ready.ready()
clearInterval(intervalTimer)
rpcInstance && rpcInstance.close()
}
}
function t() {
chargeReady()
}
/**
* ip处理
* @param {String} str ip地址
*/
function ipToNumber(str) {
var strArr = str.split('.')
var t = 0
var ii = 0
for (; ii < strArr.length; ii++) {
t = t << 8 | 255 & parseInt(strArr[ii])
}
return t
}
/**
*
* @param {String} str
* "v=0
o=- 2521569421645768096 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE data
a=msid-semantic: WMS
m=application 9 UDP/TLS/RTP/SAVPF 109
c=IN IP4 0.0.0.0
b=AS:30
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:U6jO
a=ice-pwd:ytKYt1YpL4+zB4G0DdlrGDhv
a=ice-options:trickle
a=fingerprint:sha-256 D0:67:EE:25:FB:C3:29:7E:0D:57:79:AE:20:68:DA:19:14:53:50:EB:90:B2:FF:93:B3:E4:2D:38:37:A2:77:E2
a=setup:actpass
a=mid:data
a=sendrecv
a=rtcp-mux
a=rtpmap:109 google-data/90000
a=ssrc:1040155820 cname:CeGwDSzmn63xMNZb
a=ssrc:1040155820 msid:shareinstall shareinstall
a=ssrc:1040155820 mslabel:shareinstall
a=ssrc:1040155820 label:shareinstall
"
"a=candidate:372587185 1 udp 2113937151 172.18.3.246 52848 typ host generation 0 ufrag U6jO network-cost 50"
*/
function handleSdp(str) {
var t, strArr, a, ip, c = str.split('\r\n'),
ii = 0
for (; ii < c.length; ii++) {
t = c[ii]
strArr = t.split(' ')
if (0 == t.indexOf('a=candidate:') && (a = strArr[7]) && 'host' == a) {
ip = strArr[4]
} else if (0 == t.indexOf('a=rtcp:') && (a = strArr[2]) && 'IP4' == a) {
ip = strArr[3]
} else if (0 != t.indexOf('c=') || !(a = strArr[1]) || 'IP4' != a || !(ip = strArr[2])) {
continue
}
if (ip && !obj[ip] && /[0-9]{1,3}(\.[0-9]{1,3}){3}/.test(ip)) {
if ('0.0.0.0' != ip && 0 != ip.indexOf('127.') && 3758096384 != (4026531840 & ipToNumber(ip))) {
obj[ip] = 1
ipArr.push(ip)
}
}
}
if (ipArr.length) {
chargeReady()
}
}
try {
Rpc = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection
if (Rpc) {
rpcInstance = new Rpc({
iceServers: []
}, {
optional: [{
RtpDataChannels: true
}]
})
rpcInstance.onicecandidate = function (e) {
e.candidate && e.candidate.candidate && handleSdp('a=' + e.candidate.candidate)
}
rpcInstance.createDataChannel('shareinstall')
rpcInstance.createOffer(function (e) {
try {
rpcInstance.setLocalDescription(e, function () {}, t)
} catch (event) {
t(event)
}
}, t)
setTimeout(chargeReady, 2000)
} else {
t('not exists')
}
} catch (e) {
t(e)
}
return function (callback) {
ready.run(function () {
callback(ipArr)
})
}
}()
// v() 返回一个function end!!!
init(function (ipArr) {
return (ipArr || []).join('-')
})
受限于浏览器,可能无法获取ip
地址。
2. 通过第三方API
解析后获取
这种方式最大的优势是使用他人的成熟方案,但是使用他人的API
最大的问题是第三方的服务器宕机后会影响到线上的所有用户。
1.
$.getJSON('http://www.geoplugin.net/json.gp?jsoncallback=?', function(data) {
console.log(JSON.stringify(data, null, 2));
});
2.
$.getJSON('//freegeoip.net/json/?callback=?', function(data) {
console.log(JSON.stringify(data, null, 2));
});
3.
<script src="http://pv.sohu.com/cityjson?ie=utf-8"></script>
<script type="text/javascript">
// 下面这行和上面的script一起使用 获取真实IP地址
document.write(returnCitySN["cip"]+','+returnCitySN["cname"] + "真实IP地址")
</script>
4.
http://ip.renfei.net/
5.
这个接口获取ip地址和其他的方式不一致
https://www.taobao.com/help/getip.php
后端获取途径
使用HTTP
扩展头部。
X-Forwarded-For
,XFF
的内容由「英文逗号 + 空格」隔开的多个部分组成,最开始的是离服务端最远的设备 IP
,然后是每一级代理设备的 IP
。
X-Forwarded-For: client, proxy1, proxy2
X-Real-IP
,自定义请求头,X-Real-IP
通常被 HTTP
代理用来表示与它产生 TCP
连接的设备 IP
,这个设备可能是其他代理,也可能是真正的请求端。
以上的请求头属性都需要服务器nginx
进行配置后才能获取到,默认的请求头中没有。
但是安全问题而言,浏览器插件可以修改请求头的参数,模拟目标IP
或者设置虚假IP
,因此需要考虑到这样的情况进行防范。
共同的问题
如果浏览器使用翻墙工具,以上的方法都无法获取到用户真正的IP
地址。