You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JQuery通过PHP调用API时AJAX POST请求出错

问题分析与解决方案

核心问题排查

你的POST请求失败的核心原因集中在PHP文件中,存在以下关键错误:

1. PHP未输出有效响应内容

api.php和earthquakes.php都没有将获取到的GeoNames API数据输出给前端。虽然设置了JSON响应头,但缺少echo输出解析后的JSON数据,前端AJAX接收不到有效内容,触发错误回调。

2. 调试输出破坏JSON格式

代码中的var_dump($_REQUEST['North'])和var_dump($_REQUEST)会输出非JSON格式的调试文本,导致响应内容不符合JSON规范,AJAX的dataType: 'json'解析失败。

3. 缺乏请求错误处理

没有判断CURL请求是否成功,若GeoNames API请求失败,无法定位问题根源。


修复后的PHP代码

api.php 修复版

<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);

// 验证必填POST参数是否存在
if (!isset($_POST['North'], $_POST['South'], $_POST['East'], $_POST['West'])) {
    header('Content-Type: application/json; charset=UTF-8');
    echo json_encode(['error' => '缺少必要坐标参数']);
    exit;
}

// 构造GeoNames请求URL,对参数进行URL编码
$url = 'http://api.geonames.org/weatherJSON?north=' . urlencode($_POST['North']) .
    '&south=' . urlencode($_POST['South']) .
    '&east=' . urlencode($_POST['East']) .
    '&west=' . urlencode($_POST['West']) .
    '&username=kyleghilotti';

$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);

$data = curl_exec($ch);

// 检查CURL请求是否出错
if(curl_errno($ch)){
    $error_msg = curl_error($ch);
    curl_close($ch);
    header('Content-Type: application/json; charset=UTF-8');
    echo json_encode(['error' => 'CURL请求失败: ' . $error_msg]);
    exit;
}

curl_close($ch);
$decode = json_decode($data, true);

// 输出JSON格式响应
header('Content-Type: application/json; charset=UTF-8');
echo json_encode($decode);
?>

earthquakes.php 修复版

<?php
ini_set('display_errors', 'On');
error_reporting(E_ALL);

// 验证必填POST参数
if (!isset($_POST['North'], $_POST['South'], $_POST['East'], $_POST['West'])) {
    header('Content-Type: application/json; charset=UTF-8');
    echo json_encode(['error' => '缺少必要坐标参数']);
    exit;
}

// 构造地震数据请求URL
$url = 'http://api.geonames.org/earthquakesJSON?formatted=true&north=' . urlencode($_POST['North']) .
    '&south=' . urlencode($_POST['South']) .
    '&east=' . urlencode($_POST['East']) .
    '&west=' . urlencode($_POST['West']) .
    '&username=kyleghilotti&style=full';

$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);

$data = curl_exec($ch);

// 检查CURL错误
if(curl_errno($ch)){
    $error_msg = curl_error($ch);
    curl_close($ch);
    header('Content-Type: application/json; charset=UTF-8');
    echo json_encode(['error' => 'CURL请求失败: ' . $error_msg]);
    exit;
}

curl_close($ch);
$decode = json_decode($data, true);

header('Content-Type: application/json; charset=UTF-8');
echo json_encode($decode);
?>

前端JS优化建议

1. 完善错误调试信息

在AJAX的error回调中增加更多调试内容,方便定位问题:

error: function (jqXHR, textStatus, errorThrown) {
    console.log('请求状态:', textStatus);
    console.log('错误信息:', errorThrown);
    console.log('响应内容:', jqXHR.responseText);
}

2. 修正API返回结构取值

GeoNames的API返回结构与你当前代码中的取值不符,需调整:

  • 天气接口返回的是weatherObservations数组,而非data
  • 地震接口返回的是earthquakes数组

示例修正后的success回调:

// 天气请求回调
success: function (result) {
    console.log(JSON.stringify(result));
    if (result && result.weatherObservations && result.weatherObservations.length > 0) {
        $('#clouds').html(result.weatherObservations[0].clouds);
        $('#temperature').html(result.weatherObservations[0].temperature);
        $('#station').html(result.weatherObservations[0].stationName);
    }
}

// 地震请求回调
success: function (result) {
    console.log(JSON.stringify(result));
    if (result && result.earthquakes && result.earthquakes.length > 0) {
        // 取第一条地震数据示例,可按需调整
        $('#depth').html(result.earthquakes[0].depth);
        $('#lng').html(result.earthquakes[0].lng);
        $('#magnitude').html(result.earthquakes[0].magnitude);
        $('#lat').html(result.earthquakes[0].lat);
    }
}

3. 前端参数验证

提交前验证输入框是否为空,避免无效请求:

$('#coordinates').click(function (e) {
    e.preventDefault();
    const north = $('#North').val();
    const south = $('#South').val();
    const east = $('#East').val();
    const west = $('#West').val();
    if (!north || !south || !east || !west) {
        alert('请填写所有坐标参数');
        return;
    }
    // 后续AJAX请求代码
});

内容的提问来源于stack exchange,提问作者Kyle Ghilotti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 21:54:59