如何修改JavaScript函数以适配AJAX调用PHP天气接口?
解决方案
一、先修复你的PHP接口问题
你的PHP代码存在几个会导致功能失效的问题,先修正后才能正常使用:
echo var_dump($result, $url);会破坏JSON输出格式,必须删除- OpenWeatherMap OneCall API返回的结构中没有
geonames字段,原代码赋值$output['data'] = $decode['geonames'];会导致数据为空 - 缺少请求失败的错误处理逻辑
修复后的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模态框(通用逻辑可适配其他模态框),步骤如下:
- 将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>
- 编写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'); } });
- 触发模态框的按钮示例
在国家列表中,给按钮添加经纬度属性:
<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
相关产品推荐
相关产品推荐

