大家好,我是冰茶,容我收场先讲个故事。
故事的经由是如许的:
有一天,产物同砚突发奇想,他想猎取到下单用户的地舆位置散布,以便来统计用户群的散布,进而为后期的按地区正确推行运动来做准备。
- me:这个简朴啊,下单的时刻,给个地舆定位的要求,来猎取用户所在位置就行啊,如许的话还正确……
- 产物兄:这个计划须要斟酌下,假如如果要求用户的定位信息,起首呢,能够会引起用户的恶感,毕竟我们这个产物,从头至尾都没有效到过定位,倏忽啪的一下来个弹窗,用户一定一是蒙逼,说你从头至尾都没有定位功用,要个定位权限有毛用,二是隐私认识强点,就直接谢绝掉了,如许直接就拿不到信息,没法到达预设的结果了。其次呢,我们能少打搅用户,就少打搅用户,有句话说,悄悄地进村,打枪的不要。就是说呢,让用户流通的运用下来全部流程,让用户用的爽,一直是我们的准绳……
- 产物兄:我听说有个IP定位,这东西蛮爽的,也不打搅用户,再说IP这个东西,只需用户接见我们的效劳,相对有这个东西能拿到,我们就拿他这个东西来反查下,如许我们要的省市信息就如许得手了,而且如许的胜利概率高,不必忧郁用户谢绝定位致使数据统计不全……
- 后端同砚:IP这个东西确实能够,然则呢,我们的效劳都在负载平衡/反向代办效劳背面,后端直接拿到的IP也是前端效劳器的IP,而不是用户直连我们前端效劳器的IP,所以这个东西难办啊~
- 后端同砚:想当初我们的项目还不是前后端星散的时刻,确实是能够直接拿到IP的……
- 别的的前端同砚:嗯,我这边也相识一些,我之前看到有前端猎取IP的要领:
//建立RTCPeerConnection接口
let conn = new RTCPeerConnection({
iceServers: []
})
let noop = function(){}
conn.onicecandidate = function(ice){
if (ice.candidate){
//运用正则猎取ip
let ip_regex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/
let ip_addr = ip_regex.exec(ice.candidate.candidate)[1];
console.log(ip_addr)
conn.onicecandidate = noop
}
}
//随意建立一个叫狗的通道(channel)
conn.createDataChannel('dog')
//建立一个SDP协定要求
conn.createOffer(conn.setLocalDescription.bind(conn),noop)
作者:Illgo
链接:https://www.zhihu.com/question/20675353/answer/335325619
泉源:知乎
著作权归作者一切。贸易转载请联络作者取得受权,非贸易转载请说明出处。
以后用 WebRTC猎取IP
等关键词找了几篇相似的文章。这个比较周全。
依据相似的文章,亲身实验了下,有两个题目:
- 我们有微信站的营业,在微信环境下猎取不到IP。这个要领在Chrome和Firefox下面很好用。
- 猎取的是用户的内网IP,用拿到的IP去反查,获得的结论是局域网地点。
这还查个毛线的查,因而……这个计划被摒弃了……
- me:在Google找了一些计划,大多数计划都是经由过程前端调取一个接口,接口返回地舆定位等信息。和后端同砚说的一致,只需用户发要求,效劳器能直接拿到用户收集出口的IP信息,然后我们就调接口查一下就能够了。关于后端接口拿不到IP的题目,微信付出这边有相似的解决计划。
备注:猎取用户IP指引
- me:我们效劳器相当于在代办背面,只需找运维去设置下,应当就能够了。
- 后端同砚:这个能够斟酌,稍后我这边和运维联络下,让他们那里设置下,把用户要求代办效劳器猎取到的IP通报给我这边,如许就能够了。
因而题目解决,功德圆满~
开顽笑,要真是如许的话,这篇文章就不会涌现了😀
实际情况是如许的:
- 后端同砚:假如去设置的话,由于我们的效劳器上面不只是布置了一套项目,修正设置能够影响较大……
- 后端同砚:其次呢,前端这边有一个.Net站是设置过的,这个站是之前前后端不星散时运用的站,如今只是用来布置静态文件,然则依旧有动态代码的才能,用这个站来猎取更轻易,如今也不须要设置……
总之呢,这个使命,就落在前端这边了。
好,如今让我们整顿一下手头的资本:
一个能直接猎取到IP的站,
一个能依据IP反查所在地区的接口
你问我为啥不运用现成的效劳呢?
主如果可靠性的缘由,假如是你用的外部效劳,万一效劳挂了,一是只能比及效劳商修复,时效能够比较长,万一效劳商跑路了,还得费力的切换效劳;二是能够甩锅😀
下面是效劳端的完成。
这部份完成呢,重要包括两个部份:
- 猎取IP
- 反查IP所属地区
起首我们新建一个平常处置惩罚顺序(.ashx)
下面是代码清单:
/// <summary>
/// 猎取客户端IP地点
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public static string GetAddress(HttpRequest request)
{
//能够透过代办效劳器
string remoteAddr = request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (string.IsNullOrEmpty(remoteAddr))
{
//没有代办效劳器,假如有代办效劳器猎取的是代办效劳器的IP
remoteAddr = request.ServerVariables["REMOTE_ADDR"];
}
if (!string.IsNullOrEmpty(remoteAddr)
&& remoteAddr.IndexOf(",") != -1
&& remoteAddr.Trim().Length > 6)
remoteAddr = remoteAddr.Split(',')[0].Trim();
if (remoteAddr.Length > 15)
remoteAddr = GetIP4Address();
return remoteAddr;
}
public static string GetIP4Address()
{
string IP4Address = String.Empty;
foreach (IPAddress IPA in Dns.GetHostAddresses(HttpContext.Current.Request.UserHostAddress))
{
if (IPA.AddressFamily.ToString() == "InterNetwork")
{
IP4Address = IPA.ToString();
break;
}
}
if (!string.IsNullOrEmpty(IP4Address))
{
return IP4Address;
}
foreach (IPAddress IPA in Dns.GetHostAddresses(Dns.GetHostName()))
{
if (IPA.AddressFamily.ToString() == "InterNetwork")
{
IP4Address = IPA.ToString();
break;
}
}
return IP4Address;
}
然后呢,前端挪用下暴露出的接口,就猎取到了所须要的地舆信息。前端要求要领比较通用,就是一个很简朴的Ajax要求,这里不做演示。
以后在下单时把猎取到的省市信息传到下单接口内里,如许我们就完成了猎取到前端用户的IP,并依据IP来猎取地舆定位的需求。
好了,正文就此结束。部份代码稍后补充