你如何检测网站访问者的国家(特别是美国与否)?

时间:2010-01-28 16:49:04

标签: php javascript timezone country country-codes

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

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

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

在JavaScript或PHP中是否还有其他信息可用,除了获取IP地址和进行查找之外,还有确定的信息?

8 个答案:

答案 0 :(得分:48)

有一些免费服务可以让你从客户端进行国家和基于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

答案 1 :(得分:6)

最佳指标可能是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'];
?>

答案 2 :(得分:3)

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

HTTP Accept Header不足以确定用户区域设置。它只会告诉您用户选择的语言,这可能与他们所处的位置无关。有关here的更多信息。

答案 3 :(得分:1)

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

以下是一个非常简单的示例:

http://unmissabletokyo.com/country-detector

答案 4 :(得分:1)

Wipmania.com&amp; 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 :(得分:1)

@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 :(得分:1)

我的解决方案,简单而小巧,在此示例中,我使用语言fr-CA or en-CA

测试加拿大地区
if( preg_match( "/^[a-z]{2}\-(ca)/i", $_SERVER[ "HTTP_ACCEPT_LANGUAGE" ] ) ){

   $region = "Canada";

}

答案 7 :(得分:0)

我们可以使用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