请求太多 - Geoplugin

Posted

技术标签:

【中文标题】请求太多 - Geoplugin【英文标题】:Too Many Requests - Geoplugin 【发布时间】:2021-04-11 08:55:06 【问题描述】:

为什么在我上传我的网站后,当我尝试调用使用 Geoplugin 的函数时不断收到以下错误?即使它在本地服务器上运行良好。

我用谷歌搜索并找到了可能的答案:allow_url_fopen 必须在 php 配置中打开。我联系了我的托管支持,但他们说他们没有任何问题。

请问,我该怎么解决这个问题??

HTTP 请求失败! HTTP/1.1 429 请求过多

警告:file_get_contents(http://www.geoplugin.net/json.gp?ip=154.160.16.108):打开流失败:HTTP 请求失败! HTTP/1.1 429 Too Many Requests in /home/xxxxx/joacmedia.com/xxxx/xxx/myfunc.php on line 578

我的 PHP 函数:

//get some deatils about users using geoplugin
function jo_ip_info($ip = NULL, $purpose = "location") 
  $output = NULL; global $countries;

  if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) 
      $ip = jo_real_ip();
  

  $purpose    = str_replace(array("name", "\n", "\t", " ", "-", "_"), NULL, strtolower(trim($purpose)));
  $support    = array("country", "countrycode", "state", "region", "city", "location", "address");
  $continents = array(
      "AF" => "Africa",
      "AN" => "Antarctica",
      "AS" => "Asia",
      "EU" => "Europe",
      "OC" => "Australia (Oceania)",
      "NA" => "North America",
      "SA" => "South America"
  );
  if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support)) 
      $ipdat = json_decode(file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip));
      if (@strlen(trim($ipdat->geoplugin_countryCode)) == 2) 
          switch ($purpose) 
              case "location":
                  $output = (object) array(
                      "city"           => @$ipdat->geoplugin_city,
                      "state"          => @$ipdat->geoplugin_regionName,
                      "country"        => @$ipdat->geoplugin_countryName,
                      "country_abbr"   => @$ipdat->geoplugin_countryCode,
                      "continent"      => @$continents[strtoupper($ipdat->geoplugin_continentCode)],
                      "continent_code" => @$ipdat->geoplugin_continentCode,
                      "currency"       => @$ipdat->geoplugin_currencyCode,
                      "request_ip"     => @$ipdat->geoplugin_request,
                      "time_zone"      => @$ipdat->geoplugin_timezone,
                      "country_code"   => @$countries[$ipdat->geoplugin_countryCode]['code']
                  );
                  break;
              case "address":
                  $address = array($ipdat->geoplugin_countryName);
                  if (@strlen($ipdat->geoplugin_regionName) >= 1)
                      $address[] = $ipdat->geoplugin_regionName;
                  if (@strlen($ipdat->geoplugin_city) >= 1)
                      $address[] = $ipdat->geoplugin_city;
                  $output = implode(", ", array_reverse($address));
                  break;
              case "city":
                  $output = @$ipdat->geoplugin_city;
                  break;
              case "state":
                  $output = @$ipdat->geoplugin_regionName;
                  break;
              case "region":
                  $output = @$ipdat->geoplugin_regionName;
                  break;
              case "country":
                  $output = @$ipdat->geoplugin_countryName;
                  break;
              case "countrycode":
                  $output = @$ipdat->geoplugin_countryCode;
                  break;
          
      
  
  return $output;

 


//get real ip of a user
function jo_real_ip($ip='')




 $ip = filter_var($ip,FILTER_VALIDATE_IP)  ? $ip : $_SERVER['REMOTE_ADDR'];
  if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match_all('#\d1,3\.\d1,3\.\d1,3\.\d1,3#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) 
      foreach ($matches[0] AS $xip) 
          if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) 
              $ip = $xip;
              break;
          
      
   elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]1,3\.)3[0-9]1,3$/', $_SERVER['HTTP_CLIENT_IP'])) 
      $ip = $_SERVER['HTTP_CLIENT_IP'];
   elseif (isset($_SERVER['HTTP_CF_CONNECTING_IP']) && preg_match('/^([0-9]1,3\.)3[0-9]1,3$/', $_SERVER['HTTP_CF_CONNECTING_IP'])) 
      $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
   elseif (isset($_SERVER['HTTP_X_REAL_IP']) && preg_match('/^([0-9]1,3\.)3[0-9]1,3$/', $_SERVER['HTTP_X_REAL_IP'])) 
      $ip = $_SERVER['HTTP_X_REAL_IP'];
  
  return $ip;

 

【问题讨论】:

显然 geo-API 每次只允许一定数量的请求.. 我从昨天开始注意到......他们的文档说每分钟限制为 120 个请求。所以我不明白为什么它不能在远程服务器上工作 有一个常见问题解答,也许您可​​以通过它得到答案(例如,您的主机 IP 可能已被列入黑名单...) @LarsStegelitz ....是的,我猜是这样。并且我也在共享托管计划中......他们的 Geoplugin 常见问题解答说同一台服务器上可能有人正在使用该插件。为了解决这个问题,我必须升级到高级服务以扩展请求数量或将我的域列入白名单 【参考方案1】:

如 Geoplugin FAQ 中所述:Geoplugin 似乎阻止了 HTTP 请求,它们要求我使用高级服务。而且由于处于开发过程中,购买他们的优质服务将毫无用处。

我必须重写函数以至少使用免费且稳定的ip-api:https://ip-api.com/ 并且一切正常。

        //DETECT USER'S IP
          function jo_real_ip($ip ='',$detect_deep = TRUE)
          
            
             $ip = filter_var($ip,FILTER_VALIDATE_IP)  ? $ip : $_SERVER['REMOTE_ADDR'];
              if ($detect_deep) 
                if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match_all('#\d1,3\.\d1,3\.\d1,3\.\d1,3#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) 
                  foreach ($matches[0] AS $xip) 
                      if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) 
                          $ip = $xip;
                          break;
                      
                  
               elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]1,3\.)3[0-9]1,3$/', $_SERVER['HTTP_CLIENT_IP'])) 
                  $ip = $_SERVER['HTTP_CLIENT_IP'];
               elseif (isset($_SERVER['HTTP_CF_CONNECTING_IP']) && preg_match('/^([0-9]1,3\.)3[0-9]1,3$/', $_SERVER['HTTP_CF_CONNECTING_IP'])) 
                  $ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
               elseif (isset($_SERVER['HTTP_X_REAL_IP']) && preg_match('/^([0-9]1,3\.)3[0-9]1,3$/', $_SERVER['HTTP_X_REAL_IP'])) 
                  $ip = $_SERVER['HTTP_X_REAL_IP'];
              
              

              return $ip;

          

        //JO_IP_INFO FUNCTION WILL FEED US WITH INFORMATION ABOUT THE USER
        function jo_ip_info($ip = NULL, $purpose = "location")
          $output = NULL; global $countries;
          if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) 
                  $ip = jo_real_ip();
              
          $purpose    = str_replace(array("name", "\n", "\t", " ", "-", "_"), NULL, strtolower(trim($purpose)));
          $support    = array("country", "countrycode", "state", "region", "city", "location", "address");
          if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support)) 
            $fields= "status,continent,continentCode,country,countryCode,region,regionName,city,district,zip,lat,lon,timezone,currency,isp,org,as,query";
            $ipdat = (object) json_decode(file_get_contents("http://ip-api.com/json/$ip?fields=$fields"),TRUE); 

            if ( isset($ipdat->status) && $ipdat->status ==='success') 
              switch ($purpose) 
                case 'location':
                  $output = (object) array(
                    "city"           => @$ipdat->city,
                    "state"          => @$ipdat->regionName,
                    "country"        => @$ipdat->country,
                    "country_abbr"   => @$ipdat->countryCode,
                    "continent"      => @$ipdat->continent,
                    "continent_code" => @$ipdat->continentCode,
                    "currency"       => @$ipdat->currency,
                    "latitude"       => @$ipdat->lat,
                    "longitude"      => @$ipdat->lon,
                    "request_ip"     => @$ipdat->query,
                    "time_zone"      => @$ipdat->timezone,
                    "country_code"   => @$countries[$ipdat->countryCode]['code'],
                    "zip"            => @$ipdat->zip,
                    "organization"   => (object) array('isp'=> @$ipdat->isp,'org'=>@$ipdat->org,'org_number'=>@$ipdat->as)
                    
                  );
                break;
                case'address':
                  $output = implode(', ', array_reverse(
                    @$ipdat->country,
                    @$ipdat->state,
                    @$ipdat->city,
                    @$ipdat->district));
                break;
                case 'city':
                $output = @$ipdat->city; 
                break;
                case 'country':
                $output = @$ipdat->country;
                break;
                case 'countrycode':
                $output = $countries[$ipdat->countryCode]['code'];
                break;
                case 'state':
                $output = @$ipdat->regionName;
                break;
                case 'district':
                $output  = @$ipdat->district;
                break;
                case 'timezone':
                $output = @$ipdat->timezone;
                break;

              
            

            return $output;

          
        

【讨论】:

谢谢,我以这样的方式实现了这个案例,当 GeoPlugin 工作时,我从它那里接收数据,当没有时,我从你介绍的 ip-api 接收数据,这总是正确的请求并为我工作。

以上是关于请求太多 - Geoplugin的主要内容,如果未能解决你的问题,请参考以下文章

收到太多后续请求作为请求的响应

ORA-29273: HTTP 请求失败,ORA-29270: 打开的 HTTP 请求太多

发出太多 AFNetworking 请求时超时

ExpressJS 后端挂起太多请求

ffmpeg 每帧请求的位太多

Laravel 8 Fortify 登录显示 429 太多请求