【问题标题】:How do you detect a website visitor's country (Specifically, US or not)?您如何检测网站访问者的国家/地区(特别是美国与否)?
【发布时间】:2011-01-10 12:06:26
【问题描述】:

我需要为访问我网站的美国和非美国访问者显示不同的链接。这只是为了方便起见,所以我不是在寻找超高的准确性,而且安全或欺骗不是问题。

我知道有地理定位服务和列表,但这似乎有点过头了,因为我只需要(大致)确定此人是否在美国。

我正在考虑使用 JavaScript 来获取用户的时区,但这似乎只给出了偏移量,因此加拿大、墨西哥和南美的用户将具有与美国用户相同的价值。

除了获取 IP 地址并进行查找之外,还有其他可用的 JavaScript 或 PHP 信息吗?

【问题讨论】:

  • 我认为基于 IP 的解决方案是唯一可靠的方法。其他任何事情都可能受到用户设置的影响。基于 IP 的解决方案也可能存在偏差,但难度更大。
  • @FrustratedWithFormsDesigner - 注意他说,“这只是为了方便,所以我不是在寻找超高的准确性,安全或欺骗不是问题。”因此,基于 IP 的解决方案可能对他的需求来说太过分了。他还说,“......没有获取 IP 地址并进行查找来确定这一点吗?”

标签: php javascript timezone country country-codes


【解决方案1】:

有一些免费服务可让您从客户端进行基于国家和 ip 的地理定位。

我用过wipmania免费的JSONP服务,用起来真的很简单:

<script type="text/javascript">
  // plain JavaScript example
  function jsonpCallback(data) { 
    alert('Latitude: ' + data.latitude + 
          '\nLongitude: ' + data.longitude + 
          '\nCountry: ' + data.address.country); 
  }
</script>
<script src="http://api.wipmania.com/jsonp?callback=jsonpCallback"
        type="text/javascript"></script>

或者,如果您使用支持 JSONP 的框架,例如 jQuery,您可以:

// jQuery example
$.getJSON('http://api.wipmania.com/jsonp?callback=?', function (data) { 
  alert('Latitude: ' + data.latitude + 
        '\nLongitude: ' + data.longitude + 
        '\nCountry: ' + data.address.country); 
});

检查上面运行here的sn-p。

【讨论】:

  • 如何修改您的代码,以便使用 URL 重定向而不是警告对话框,将美国访问者带到 .COM 地址并允许加拿大访问者正常通过? (对于具有姐妹 .COM 版本网站的 .CA 版本网站)
  • onload事件中的switch语句,查看json函数返回的“country”,然后调用Server.Transfer或类似方法。
  • 非常感谢代码和链接,它的工作和真棒:)
  • 这不支持 https :(
【解决方案2】:

最好的指标可能是 HTTP Accept-Language 标头。它在 HTTP 请求中将如下所示:

GET / HTTP/1.1
Accept: */*
Accept-Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; Trident/4.0; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.21022; .NET CLR 3.5.30729; MDDC; OfficeLiveConnector.1.4; OfficeLivePatch.0.0; .NET CLR 3.0.30729)
Accept-Encoding: gzip, deflate
Host: www.google.com
Connection: Keep-Alive

您应该能够使用以下方法在 PHP 中检索它:

<?php
echo $_SERVER['HTTP_ACCEPT_LANGUAGE'];
?>

【讨论】:

  • 什么决定了接受语言?它是由操作系统设置的,还是用户可以影响它?如果我的同事将他的笔记本电脑设置为使用中文,Accept-Language 会是什么?另外,en-gb 呢?
  • 由用户的浏览器设置决定。
  • @FrustratedWithFormsDesigner:接受语言由浏览器决定。如果他们愿意,它可以由用户操作。例如,在 firefox 下,转到 Preferences > Content > Languages
  • 由浏览器设置,通常从操作系统初始化。因此,当我在加拿大时,通过设置通常在 IE 和 FF 等浏览器中调用的“语言”,我可以看起来在美国、英国或其他地方。
  • 伙计们,尤其是泰勒,这看起来可能是我需要的解决方案。正如我所说,我不在乎用户是否假装来自其他地方,因为他们当然欢迎这样做。我会花一些时间看看我是否还有其他好的选择,但谢谢!
【解决方案3】:

我会说地理定位是唯一可靠的方法。但也有一些根本没有帮助的情况。我不断访问那些认为我在法国的网站,因为我公司的骨干网在那里,所有互联网流量都通过它。

HTTP 接受标头不足以确定用户区域设置。它只告诉您用户选择的语言,这可能与他们所在的位置无关。更多关于这个here

【讨论】:

    【解决方案4】:

    Wipmania.com 和 PHP

    <?php
    $site_name = "www.your-site-name.com";
    
    function getUserCountry() {
        $fp = fsockopen("api.wipmania.com", 80, $errno, $errstr, 5);
        if (!$fp) {
            // API is currently down, return as "Unknown" :(
            return "XX";
        } else {
            $out = "GET /".$_SERVER['REMOTE_ADDR']."?".$site_name." HTTP/1.1\r\n";
            $out .= "Host: api.wipmania.com\r\n";
            $out .= "Typ: php\r\n";
            $out .= "Ver: 1.0\r\n";
            $out .= "Connection: Close\r\n\r\n";
            fwrite($fp, $out);
            while (!feof($fp)) {
                $country = fgets($fp, 3);
            }
            fclose($fp);
            return $country;
        }
    }
    ?>
    

    【讨论】:

      【解决方案5】:

      @rostislav

      或使用 cURL:

      public function __construct($site_name) {
          // create a new cURL resource
          $ch = curl_init();
      
          // set URL and other appropriate options
          curl_setopt($ch, CURLOPT_POST, 0);
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
          curl_setopt($ch, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml"));
          curl_setopt($ch, CURLOPT_URL, "http://api.wipmania.com".$_SERVER['REMOTE_ADDR']."?".$site_name);
          curl_setopt($ch, CURLOPT_HEADER, 0);
      
          // grab URL and pass it to the browser
          $response = curl_exec($ch);
          $info = curl_getinfo($ch,CURLINFO_HTTP_CODE);
      
          if (($response === false) || ($info !== 200)) {
              throw new Exception('HTTP Error calling Wipmania API - HTTP Status: ' . $info . ' - cURL Erorr: ' . curl_error($ch));
          } elseif (curl_errno($ch) > 0) {
              throw new Exception('HTTP Error calling Wipmania API - cURL Error: ' . curl_error($ch));
          }
      
          $this->country = $response;
      
          // close cURL resource, and free up system resources
          curl_close($ch);
      }
      

      【讨论】:

        【解决方案6】:

        我们可以简单地使用 Hostip API

        <?php $country_code = file_get_contents("http://api.hostip.info/country.php"); <br/>if($country_code == "US"){ echo "You Are USA"; } <br/>else{ echo "You Are Not USA";} ?>
        

        所有国家代码都在这里.. http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2

        【讨论】:

        • 是服务器端吗?所以它正在检查服务器位置而不是 cilent?
        【解决方案7】:

        我的解决方案,简单而小巧,在此示例中,我使用语言 fr-CA or en-CA 测试加拿大地区

        if( preg_match( "/^[a-z]{2}\-(ca)/i", $_SERVER[ "HTTP_ACCEPT_LANGUAGE" ] ) ){
        
           $region = "Canada";
        
        }
        

        【讨论】:

          【解决方案8】:

          根据您要区分的国家/地区,时区可能是一种非常简单的实现方式 - 我认为它非常可靠,因为大多数人都会正确设置计算机上的时钟。 (当然,使用这种技术您无法区分许多国家/地区)。

          这是一个非常简单的例子:

          http://unmissabletokyo.com/country-detector

          【讨论】:

          • 这在很多国家有共享时区的情况下不起作用。
          猜你喜欢
          • 1970-01-01
          • 2019-01-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多