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

如何修改JavaScript函数以适配AJAX调用PHP天气接口?

解决方案

一、先修复你的PHP接口问题

你的PHP代码存在几个会导致功能失效的问题,先修正后才能正常使用:

  1. echo var_dump($result, $url);会破坏JSON输出格式,必须删除
  2. OpenWeatherMap OneCall API返回的结构中没有geonames字段,原代码赋值$output['data'] = $decode['geonames'];会导致数据为空
  3. 缺少请求失败的错误处理逻辑

修复后的PHP代码:

<?php
// 生产环境请删除以下两行
ini_set('display_errors', 'On');
error_reporting(E_ALL);

$executionStartTime = microtime(true);

// 仅允许GET请求,更安全
if (!isset($_GET['lat'], $_GET['lng'])) {
    http_response_code(400);
    echo json_encode([
        'status' => [
            'code' => 400,
            'name' => 'bad_request',
            'description' => '缺少经纬度参数'
        ]
    ]);
    exit;
}

$lat = $_GET['lat'];
$lng = $_GET['lng'];
$apiKey = '01a69c43fa692a1e67ae4c9bdabb8fdc';

$url = "https://api.openweathermap.org/data/2.5/onecall?lat={$lat}&lon={$lng}&units=metric&appid={$apiKey}";

$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // 生产环境建议开启SSL验证
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);

$result = curl_exec($ch);
$curlError = curl_error($ch);
curl_close($ch);

// 处理curl请求失败
if ($curlError || !$result) {
    http_response_code(500);
    echo json_encode([
        'status' => [
            'code' => 500,
            'name' => 'server_error',
            'description' => '获取天气数据失败: ' . $curlError
        ]
    ]);
    exit;
}

$decode = json_decode($result, true);

// 处理API返回错误
if (isset($decode['cod']) && $decode['cod'] != 200) {
    http_response_code($decode['cod']);
    echo json_encode([
        'status' => [
            'code' => $decode['cod'],
            'name' => 'api_error',
            'description' => $decode['message']
        ]
    ]);
    exit;
}

$output['status']['code'] = 200;
$output['status']['name'] = "ok";
$output['status']['description'] = "success";
$output['status']['returnedIn'] = intval((microtime(true) - $executionStartTime) * 1000) . " ms";
$output['data'] = $decode; // 直接返回完整的天气数据,按需提取

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

二、修改前端适配模态框与接口

假设你用的是Bootstrap模态框(通用逻辑可适配其他模态框),步骤如下:

  1. 将CodePen的天气UI嵌入模态框
    把CodePen里的天气HTML结构放到模态框的内容区域:
<!-- 天气模态框 -->
<div class="modal fade" id="weatherModal" tabindex="-1" aria-labelledby="weatherModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="weatherModalLabel">当前天气</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <!-- 天气UI区域 -->
        <div class="weather-card">
          <div class="weather-icon">
            <img id="weatherIcon" src="" alt="天气图标">
          </div>
          <div class="weather-temp" id="weatherTemp">--°C</div>
          <div class="weather-desc" id="weatherDesc">--</div>
          <div class="weather-details">
            <div class="detail-item">
              <span>湿度:</span>
              <span id="weatherHumidity">--%</span>
            </div>
            <div class="detail-item">
              <span>风速:</span>
              <span id="weatherWind">-- m/s</span>
            </div>
          </div>
        </div>
        <!-- 加载状态 -->
        <div id="loadingState" class="d-none">加载中...</div>
        <!-- 错误提示 -->
        <div id="errorState" class="d-none text-danger"></div>
      </div>
    </div>
  </div>
</div>
  1. 编写AJAX请求逻辑
    在模态框打开时,传入目标国家的经纬度,调用PHP接口并更新UI:
// 获取模态框及状态元素
const weatherModal = document.getElementById('weatherModal');
const loadingState = document.getElementById('loadingState');
const errorState = document.getElementById('errorState');
const weatherCard = document.querySelector('.weather-card');

// 监听模态框打开事件
weatherModal.addEventListener('show.bs.modal', async (event) => {
  // 从触发按钮获取经纬度(按钮需添加data-lat、data-lng属性)
  const button = event.relatedTarget;
  const lat = button.getAttribute('data-lat');
  const lng = button.getAttribute('data-lng');

  // 切换状态显示
  loadingState.classList.remove('d-none');
  errorState.classList.add('d-none');
  weatherCard.classList.add('d-none');

  try {
    // 调用PHP接口
    const response = await fetch(`your-php-file-path.php?lat=${lat}&lng=${lng}`);
    const data = await response.json();

    if (data.status.code !== 200) {
      throw new Error(data.status.description);
    }

    // 提取当前天气数据
    const currentWeather = data.data.current;
    // 更新UI内容
    document.getElementById('weatherTemp').textContent = `${Math.round(currentWeather.temp)}°C`;
    document.getElementById('weatherDesc').textContent = currentWeather.weather[0].description;
    document.getElementById('weatherHumidity').textContent = `${currentWeather.humidity}%`;
    document.getElementById('weatherWind').textContent = `${currentWeather.wind_speed} m/s`;
    // 设置天气图标
    const iconId = currentWeather.weather[0].icon;
    document.getElementById('weatherIcon').src = `https://openweathermap.org/img/wn/${iconId}@2x.png`;

    // 显示天气卡片
    weatherCard.classList.remove('d-none');
    loadingState.classList.add('d-none');
  } catch (err) {
    // 显示错误信息
    errorState.textContent = `获取天气失败: ${err.message}`;
    errorState.classList.remove('d-none');
    loadingState.classList.add('d-none');
  }
});
  1. 触发模态框的按钮示例
    在国家列表中,给按钮添加经纬度属性:
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#weatherModal" data-lat="35.6762" data-lng="139.6503">
  查看东京天气
</button>

三、关键注意事项

  • 确保PHP文件和前端页面在同一域名下(或配置CORS跨域规则)
  • 生产环境请删除PHP中的错误显示代码,并开启SSL验证
  • 可从API返回的data.daily字段提取未来天气预报,扩展UI内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 21:10:31