hcnak.blog

posted at 2015-11-08 18:10:19 +0000

关于ASP.NET获得访问者IP的问题得到的IP地址不准确!与解决办法

前段时间,大概在7月份的时候,我做了一个工具网站,其中有一项功能是获得访问者IP地址及根据IP地址来查询访问者的ISP及地区。当时弄了很久,都没弄出啥来,我指的是获得的IP地址不准确。后来我继续Google解决方案,终于把它给解决了。之后就再也没管了,渐渐忘了这个。

直到前几天,我收到了一封邮件,内容里说道他也遇到了这个问题,在CSDN上找到了我之前的帖子,看我已经解决了这个问题,所以想知道我是怎么解决的。(我去,当时我也是在网上找到的解决方案,再加上过去了这么久了,我咋会知道)好吧,不过我还是决定来理一理这个问题。下面进入正题。

所有代码均为 C# .NetFramework4.0

先来说说之前那个版本吧

下面这个可以获得IP,但是,,不准确 -_-

public static string GetIP() {
 string result = String.Empty;
 result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
 if (string.IsNullOrEmpty(result)) {
  result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
 }
 if (string.IsNullOrEmpty(result)) {
  result = HttpContext.Current.Request.UserHostAddress;
 }
 if (string.IsNullOrEmpty(result)) {
  return "127.0.0.1";
 }
 return result;
}
<这个是在我的网站上得到的结果> [![asp_get_ip_1](https://raw.githubusercontent.com/ankanch/blog/master/images/wp-content/uploads/2015/11/asp_get_ip_1.jpg)](https://raw.githubusercontent.com/ankanch/blog/master/images/wp-content/uploads/2015/11/asp_get_ip_1.jpg) <这个是在腾讯IP分享计划网站上得到的结果> [![asp_get_ip_3](https://raw.githubusercontent.com/ankanch/blog/master/images/wp-content/uploads/2015/11/asp_get_ip_3.jpg)](https://raw.githubusercontent.com/ankanch/blog/master/images/wp-content/uploads/2015/11/asp_get_ip_1.jpg) <这个是在GetMyIP网站上得到的结果> [![asp_get_ip_2](https://raw.githubusercontent.com/ankanch/blog/master/images/wp-content/uploads/2015/11/asp_get_ip_2.jpg)](https://raw.githubusercontent.com/ankanch/blog/master/images/wp-content/uploads/2015/11/asp_get_ip_2.jpg) 下面来讲讲这个版本: 这个版本是利用HTTP Header来获得IP地址的。假设Header里面包含的真实IP,那先默认它为真实IP, 但是如果包含`X_FORWARDED_FOR`则说明用户使用了代理,那就把`X_FORWARDED_FOR`作为用户真实IP。如果两者都没有,就取`REMOTE_ADDR`作为用户真实IP。 因为当使用者通过代理服务器时,`REMOTE_ADDR`会显示为代理服务器的IP。部分代理服务器会将使用者的原始真实IP放在客户端的IP或的X转发,对于在header中传递,这样就可以取得真实IP。 * 我先用了`HttpContext`中的`request`的`HTTP_X_FORWARDED_FOR`变量来判断用户是否使用了代理 `HttpContext`封装了有关个别 HTTP 请求的所有 HTTP 特定的信息。 `Current`则是表示为当前HTTP请求设置对象 `SerVaeribles[]`则是一系列服务器变量的集合,对于详细的属性,你们可以看这里,这里有个[**Server.Variables** **属性大全**](http://www.cnblogs.com/zwffff/archive/2009/04/18/1438567.html) * 再简单的用了`HttpContext`中request的`REMOTE_ADDR`变量来获得用户的IP **REMOTE_ADDR**即获得用户真实IP * 再通过`HttpContext`中request的`UserHostAddress`来得到IP **UserHostAddress**是用来获取远程客户端的 IP 主机地址。 要是以上都不满足,就说明用户/服务器在本地,IP自然就是127.0.0.1了 ## 为什么获得的IP会不一样呢? 我在网上查了很久,大概是这样的: [「**任何從客戶端取得的資料都是不可信任的!**」](http://devco.re/blog/2014/06/19/client-ip-detection/) ~~其实我也没搞懂什么意思。。。大概是说你PC上的某些安全软件或者浏览器会修改head数据吧~~ 2019更新:使用代理时IP为代理IP,然后就是某些安全软件可能修改HTTP Header。 ## 这是修改之后的版本: ```C# protected String GetUser_IP() { string VisitorsIPAddr = string.Empty; if (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null) { VisitorsIPAddr = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString(); } else if (HttpContext.Current.Request.UserHostAddress.Length != 0) { VisitorsIPAddr = HttpContext.Current.Request.UserHostAddress; } return VisitorsIPAddr; } ``` 但是我们的确获得了真实IP: [![asp_get_ip_4](https://raw.githubusercontent.com/ankanch/blog/master/images/wp-content/uploads/2015/11/asp_get_ip_41.jpg)](https://raw.githubusercontent.com/ankanch/blog/master/images/wp-content/uploads/2015/11/asp_get_ip_41.jpg) P.S.写这篇文章的时候我正在成都读书-_- ## 再来谈谈如何根据用户IP获得其地理位置和ISP吧 这个嘛,我利用了淘宝IP库的API,我只需要通过WebAPI将要查询的IP传给淘宝,然后淘宝就会以JSON数据格式,把对应IP说的ISP提供商和地理位置信息回传给我。 [淘宝WebAPI参考:http://ip.taobao.com/instructions.php](http://ip.taobao.com/instructions.php) 返回的数据像这样: ```json { "code": 0, "data": { "ip": "210.75.225.254", "country": "u4e2du56fd", "area": "u534eu5317", "region": "u5317u4eacu5e02", "city": "u5317u4eacu5e02", "county": "", "isp": "u7535u4fe1", "country_id": "86", "area_id": "100000", "region_id": "110000", "city_id": "110000", "county_id": "-1", "isp_id": "100017" } } ``` 所以,我写了个通过IP得到相关信息的函数 ```c# public static string GetUserLocation(string IPaddr) //根据IP地址获得用户所在区域 { try { WebClient webGetting = new WebClient(); string userIP = IPaddr; string ipQueryResult = webGetting.DownloadString("http://ip.taobao.com/service/getIpInfo.php?ip=" + userIP); return ipQueryResult; } catch { return string.Empty; } } ``` 文章参考了[_如何正確的取得使用者 IP?_](http://devco.re/blog/2014/06/19/client-ip-detection/) --- --- `© kanch` → [zl AT kanchz DOT com](kanchisme@gmail.com) _last updated on 2022-07-27 01:57:54 +0000_