求助:Geonames Weather API无法获取数据,请求排查问题
排查Geonames Weather API数据获取失败问题
以下是针对你的代码和问题的具体排查与修复方案:
1. 先验证API请求本身的有效性
直接在浏览器地址栏构造完整请求URL(替换为你的实际参数和用户名),比如:
http://api.geonames.org/weatherJSON?formatted=true&north=44.1&south=-9.9&east=-22.4&west=55.2&username=karomal89&style=full
- 如果浏览器返回空数据或错误信息,说明问题出在API层面:
- 确认你的Geonames用户名已完成邮箱激活(免费账户需验证才能使用API)
- 检查免费账户的请求次数限制是否耗尽
- 确认经纬度参数范围是否合理(示例范围是否真的存在气象站)
2. 修复PHP代码的错误处理缺陷
你的PHP代码缺少关键错误捕获逻辑,导致无法定位问题,修改后代码如下:
<?php ini_set('display_errors', 'On'); error_reporting(E_ALL); $executionStartTime = microtime(true); // 改用$_POST匹配前端请求方式,对参数做URL编码 $north = urlencode($_POST['north'] ?? ''); $south = urlencode($_POST['south'] ?? ''); $east = urlencode($_POST['east'] ?? ''); $west = urlencode($_POST['west'] ?? ''); $username = 'karomal89'; $url = "http://api.geonames.org/weatherJSON?formatted=true&north={$north}&south={$south}&east={$east}&west={$west}&username={$username}&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(curl_errno($ch)) { $output['status']['code'] = "500"; $output['status']['name'] = "curl_error"; $output['status']['description'] = curl_error($ch); curl_close($ch); header('Content-Type: application/json; charset=UTF-8'); echo json_encode($output); exit; } curl_close($ch); // 检查JSON解析是否成功 $decode = json_decode($result, true); if(!$decode) { $output['status']['code'] = "500"; $output['status']['name'] = "json_decode_error"; $output['status']['description'] = "API返回无效JSON内容"; $output['status']['returnedIn'] = intval((microtime(true) - $executionStartTime) * 1000) . " ms"; header('Content-Type: application/json; charset=UTF-8'); echo json_encode($output); exit; } // 检查API是否返回错误信息 if(isset($decode['status'])) { $output['status']['code'] = $decode['status']['value']; $output['status']['name'] = $decode['status']['name']; $output['status']['description'] = $decode['status']['message']; } else { $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'] ?? []; header('Content-Type: application/json; charset=UTF-8'); echo json_encode($output); ?>
- 改用
$_POST匹配前端请求方式,避免$_REQUEST的歧义 - 对参数做
urlencode处理,防止特殊字符破坏URL结构 - 增加CURL错误捕获,直接暴露请求API时的网络问题
- 检查JSON解析结果,避免API返回非JSON内容导致后续报错
- 根据API返回的错误状态(如用户名无效、参数错误)动态设置响应状态码
3. 完善AJAX代码的错误处理与输入校验
你的AJAX仅处理成功场景,失败时无法定位问题,修改后代码如下:
$("#weatherBtn").click(function () { // 先验证输入是否完整 const north = $("#north").val(); const south = $("#south").val(); const east = $("#east").val(); const west = $("#west").val(); if(!north || !south || !east || !west) { alert('请填写所有经纬度参数'); return; } $.ajax({ url: "libs/php/weather.php", type: "POST", dataType: "json", data: { north, south, east, west }, success: function (result) { // 先检查是否有有效数据返回 if(result.data && result.data.length > 0) { $("#txtA").html(result.data[0].stationName); $("#txtB").html(result.data[0].temperature); $("#txtC").html(result.data[0].clouds); $("#txtD").html(result.data[0].humidity); } else { alert('该区域没有气象站数据'); } }, // 新增错误回调,打印详细错误信息 error: function(xhr, status, error) { console.log('请求错误详情:', xhr.responseText); alert('请求失败,请查看浏览器控制台日志'); } }); });
- 增加输入验证,避免空参数提交给API
- 新增
error回调,在控制台查看PHP返回的错误详情 - 成功回调中先检查数据是否存在,避免数组越界报错
4. 其他排查点
- 检查PHP的curl扩展是否启用(可通过
phpinfo()查看) - 确认服务器能访问Geonames的API地址(部分服务器会限制外部请求)
- 查看浏览器控制台的Network面板,分析AJAX请求的状态码和响应内容,快速定位问题环节
内容的提问来源于stack exchange,提问作者Karolis
相关产品推荐
相关产品推荐

