使用Leaflet与Laravel无法获取海拔数据的问题求助
问题描述
点击Leaflet地图可正常获取坐标填充到表单,但无法获取海拔,出现两个错误:
- GET请求返回500错误:
https://calefeno.arca.buzz/getElevation?lat=46.156589&lng=8.978877 - JSON解析错误:
Unexpected token '<', "<!DOCTYPE "... is not valid JSON
OpenTopoData API单独调用正常(如https://api.opentopodata.org/v1/eudem25m?locations=46,9),但集成到Laravel10(基于Quick Admin Panel)项目中失效。
相关代码
JavaScript代码
// on click (or tap), populate the fields: coordinates and altitude map.on('click', function (e) { var lat = e.latlng.lat.toFixed(6); var lng = e.latlng.lng.toFixed(6); // Update coordinates field document.getElementById('coordinates').value = `${lat},${lng}`; // print lat and lng in console log console.log("You clicked the map at " + lat + ", " + lng); // Fetch elevation data from your Laravel backend fetch(`/getElevation?lat=${lat}&lng=${lng}`) // Update the URL to your Laravel route .then(response => response.json()) .then(data => { if (data && data.results && data.results.length > 0) { var altitude = data.results[0].elevation.toFixed(2); // Altitude to two decimal places console.log('Altitude:', altitude); // Update altitude field in the view document.getElementById('altitude').value = altitude; // Update coordinates field //document.getElementById('coordinates').value = `${lat},${lng}`; } }) .catch(error => console.error('Error fetching altitude:', error)); });
Laravel控制器代码
use App\Models\PlantObserved; class ElevationController extends Controller { public function __construct() { //CORS policy $this->middleware('cors'); } public function getElevation(Request $request) { Log::info("getElevation method called."); $lat = $request->input('lat'); $lng = $request->input('lng'); // Call the OpenTopoData API $response = Http::get("https://api.opentopodata.org/v1/eudem25m", [ 'locations' => "$lat,$lng" ]); return response()->json($response->json()); } }
视图相关代码
<div class="form-group"> <label for="altitude">{{ trans('cruds.plantObserved.fields.altitude') }}</label> <input class="form-control {{ $errors->has('altitude') ? 'is-invalid' : '' }}" type="text" name="altitude" id="altitude" value="{{ old('altitude', '') }}"> @if ($errors->has('altitude')) <div class="invalid-feedback"> {{ $errors->first('altitude') }} </div> @endif <span class="help-block">{{ trans('cruds.plantObserved.fields.altitude_helper') }}</span> </div> <div class="form-group"> <label for="coordinates">{{ trans('cruds.plantObserved.fields.coordinates') }}</label> <input class="form-control {{ $errors->has('coordinates') ? 'is-invalid' : '' }}" type="text" placeholder="Clicca sulla mappa per ricevere le coordinate" name="coordinates" id="coordinates" value="{{ old('coordinates', '') }}"> @if ($errors->has('coordinates')) <div class="invalid-feedback"> {{ $errors->first('coordinates') }} </div> @endif <span class="help-block">{{ trans('cruds.plantObserved.fields.coordinates_helper') }}</span> </div>
排查与解决步骤
定位500错误根源
查看Laravel项目storage/logs/laravel.log文件,获取详细报错信息。常见触发点:- 控制器缺失门面引入:代码中使用了
Log::info和Http::get,但未引入对应的Facades,会直接抛出致命错误。 - 路由未注册:确认
routes/web.php或routes/api.php中是否添加了getElevation的路由规则,示例:Route::get('/getElevation', [ElevationController::class, 'getElevation']); - CORS中间件失效:如果是API路由,优先使用Laravel自带的CORS配置(修改
config/cors.php),而非自定义中间件。
- 控制器缺失门面引入:代码中使用了
修复控制器依赖问题
在控制器顶部补充缺失的引入代码,移除未使用的PlantObserved模型:use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Http; use Illuminate\Http\Request; class ElevationController extends Controller { // ... 其余代码 }增加HTTP请求异常处理
为OpenTopoData的请求添加异常捕获,避免请求失败时返回非JSON内容:public function getElevation(Request $request) { Log::info("getElevation method called."); $lat = $request->input('lat'); $lng = $request->input('lng'); try { $response = Http::get("https://api.opentopodata.org/v1/eudem25m", [ 'locations' => "$lat,$lng" ]); if (!$response->successful()) { return response()->json(['error' => '获取海拔数据失败'], $response->status()); } return response()->json($response->json()); } catch (\Exception $e) { Log::error('海拔请求错误: ' . $e->getMessage()); return response()->json(['error' => '服务器内部错误'], 500); } }前端优化错误处理逻辑
在fetch时先检查响应状态,再解析JSON,避免非JSON内容导致解析失败:fetch(`/getElevation?lat=${lat}&lng=${lng}`) .then(response => { if (!response.ok) { throw new Error(`HTTP错误: ${response.status}`); } return response.json(); }) .then(data => { if (data && data.results && data.results.length > 0) { var altitude = data.results[0].elevation.toFixed(2); console.log('海拔:', altitude); document.getElementById('altitude').value = altitude; } else if (data.error) { console.error('海拔API错误:', data.error); } }) .catch(error => console.error('获取海拔失败:', error));
内容的提问来源于stack exchange,提问作者LittleDuck
相关产品推荐
相关产品推荐

