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

Posted

技术标签:

【中文标题】您如何检测网站访问者的国家/地区(特别是美国与否)?【英文标题】: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 地址并进行查找来确定这一点吗?” 【参考方案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 :( 我一般用geo-ip.net/locate?query=***.com&format=json它支持ssl连接【参考方案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

【讨论】:

这在很多国家有共享时区的情况下不起作用。

以上是关于您如何检测网站访问者的国家/地区(特别是美国与否)?的主要内容,如果未能解决你的问题,请参考以下文章

如何检测访客的国家/地区? [复制]

限制访问特定国家/地区的 PHP 网站

如何检测 IP 属于美国的特定州

如何在 PHP 中按国家/地区记录 IP?

如何检测访客国家

根据访问者 IP 地址(国家/地区)将主网站重定向到子域