Geonames API返回空数组:网页国家信息查询无数据问题排查
问题分析与修复方案
你的代码存在几个关键问题,导致API返回空数组或前端无法正确处理响应:
一、后端PHP的核心问题
参数检查顺序错误
你先发起了API请求,再检查country参数是否存在。如果用户没输入国家,不仅白发起了一次无效请求,还会因为$decode未定义导致报错。应该先做参数校验,再请求API。未处理API请求失败的情况
curl_exec()可能返回false(比如网络错误、API地址错误),直接输出会导致前端解析JSON失败。需要添加curl错误处理。未对用户输入做URL编码
用户输入的国家名称如果包含空格、特殊字符,会破坏API请求URL的格式,必须用urlencode()转义参数。返回结构与前端期望不匹配
前端期望响应包含status和data字段,但你直接返回了Geonames的原始响应(结构是{"geonames": [...]}),导致前端的result.status判断永远不成立。
修复后的后端PHP代码
<?php ini_set('display_errors', 'On'); error_reporting(E_ALL); header("Access-Control-Allow-Origin: *"); header("Content-Type: application/json"); $executionStartTime = microtime(true); $output = []; // 先校验参数 if (!isset($_REQUEST['country']) || trim($_REQUEST['country']) === '') { $output['status']['code'] = "400"; $output['status']['name'] = "Bad Request"; $output['status']['description'] = "Country parameter is missing or empty"; $output['status']['returnedIn'] = intval((microtime(true) - $executionStartTime) * 1000) . " ms"; $output['data'] = []; echo json_encode($output); exit(); } // 转义用户输入,避免URL格式错误 $country = urlencode(trim($_REQUEST['country'])); $url = "http://api.geonames.org/countryInfoJSON?formatted=true&country={$country}&username=susan.alexander&style=full"; $ch = curl_init(); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_URL, $url); $result = curl_exec($ch); // 处理curl请求失败 if ($result === false) { $output['status']['code'] = "500"; $output['status']['name'] = "Server Error"; $output['status']['description'] = "Failed to connect to Geonames API: " . curl_error($ch); $output['status']['returnedIn'] = intval((microtime(true) - $executionStartTime) * 1000) . " ms"; $output['data'] = []; curl_close($ch); echo json_encode($output); exit(); } curl_close($ch); // 解析API响应 $decode = json_decode($result, true); // 处理Geonames返回空数组的情况 if (!isset($decode['geonames']) || empty($decode['geonames'])) { $output['status']['code'] = "404"; $output['status']['name'] = "Not Found"; $output['status']['description'] = "No country information found for the provided input"; $output['status']['returnedIn'] = intval((microtime(true) - $executionStartTime) * 1000) . " ms"; $output['data'] = []; } else { // 匹配前端期望的结构,取第一个结果(Geonames返回的是数组) $output['status']['code'] = "200"; $output['status']['name'] = "ok"; $output['status']['description'] = "Success"; $output['status']['returnedIn'] = intval((microtime(true) - $executionStartTime) * 1000) . " ms"; $output['data'] = $decode['geonames'][0]; } echo json_encode($output); ?>
二、前端JS的问题
- 未处理API返回空数据的情况
当前端拿到result.data为空时,需要显示友好提示,而不是直接报错。 - 字段映射可能不匹配
Geonames返回的字段名是capital、population、currencyCode(不是currency)、languages(不是language)、lat/lng(不是coordinates),需要对应正确的字段名。
修复后的前端JS代码
$('#btnRun').click(function() { $.ajax({ url: "libs/countryInfo.php", type: 'GET', dataType: 'json', data: { country: $('#country').val().trim(), }, success: function(result) { console.log(result); if (result && result.status && result.status.name === "ok") { const data = result.data; // 对应Geonames的实际字段名 $('#txtCapital').html(data.capital || 'N/A'); $('#txtPopulation').html(data.population ? parseInt(data.population).toLocaleString() : 'N/A'); $('#txtCurrency').html(data.currencyCode || 'N/A'); // 处理多语言格式,比如"en-GB,cy-GB" $('#txtLanguage').html(data.languages ? data.languages.split(',')[0].split('-')[0] : 'N/A'); $('#txtCoordinates').html(`${data.lat}, ${data.lng}` || 'N/A'); $('#countryInfoResults').show(); } else { console.error("Error:", result.status.description); // 显示错误提示给用户 $('#countryInfoResults').hide(); alert(result.status.description || 'Unknown error occurred'); } }, error: function(jqXHR, textStatus, errorThrown) { console.error("AJAX Error:", textStatus, errorThrown); $('#countryInfoResults').hide(); alert('Failed to fetch country information. Please try again later.'); } }); });
额外排查点
- 确认你的Geonames用户名
susan.alexander是有效的,且没有超过API调用限额(Geonames免费版有限制)。 - 测试时可以直接在浏览器地址栏访问后端拼接的URL,看返回内容是否正常,比如:
http://api.geonames.org/countryInfoJSON?formatted=true&country=China&username=susan.alexander&style=full,检查是否返回正确的geonames数组。
内容的提问来源于stack exchange,提问作者SusanAlexanderFSD
相关产品推荐
相关产品推荐

