Laravel项目中隐藏Breezometer API密钥实现空气质量热力图
解决方案:Laravel代理Breezometer瓦片请求隐藏API密钥
你的思路完全正确——通过Laravel做反向代理就能避免暴露API密钥,之前的控制器失败是因为两个关键问题:没替换瓦片坐标参数,以及没有正确返回图片响应。下面是完整的可行方案:
1. 配置Laravel路由
在routes/web.php(或api.php,根据你的项目结构)中添加代理路由,接收瓦片的缩放级、坐标参数:
Route::get('/tiles/breezometer/{z}/{x}/{y}', [TileProxyController::class, 'fetchBreezometerTile']);
(注意:你需要先创建TileProxyController或者复用现有控制器)
2. 编写代理控制器方法
替换你之前的错误代码,用以下逻辑:
<?php namespace App\Http\Controllers; use Illuminate\Support\Facades\Http; use Illuminate\Http\Response; class TileProxyController extends Controller { public function fetchBreezometerTile(int $z, int $x, int $y) { // 从环境变量读取密钥(绝对不要硬编码!) $apiKey = env('BREEZOMETER_API_KEY'); if (!$apiKey) { abort(500, 'Breezometer API key not configured'); } // 拼接带密钥的Breezometer瓦片URL $tileUrl = sprintf( 'https://tiles.breezometer.com/v1/air-quality/breezometer-aqi/current-conditions/%d/%d/%d.png?key=%s', $z, $x, $y, $apiKey ); // 发起请求到Breezometer $response = Http::get($tileUrl); // 请求失败时返回404 if ($response->failed()) { abort(404); } // 返回图片响应,带上正确的HTTP头 return response($response->body(), Response::HTTP_OK, [ 'Content-Type' => $response->header('Content-Type'), 'Cache-Control' => 'public, max-age=3600', // 缓存1小时,可根据API规则调整 ]); } }
3. 修改前端Leaflet代码
把原来直接请求Breezometer的URL换成你的Laravel代理路由,不需要再带密钥:
let map = L.map('map').setView([28.7041, 77.1025], 13); L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© <a href="http://www.openstreetmap.org/copyright" rel="nofollow noreferrer">OpenStreetMap</a>' }).addTo(map); // 替换为Laravel代理路由 L.tileLayer('/tiles/breezometer/{z}/{x}/{y}', { tms: false, opacity: 0.65, maxNativeZoom: 19 }).addTo(map);
关键注意事项
- 把API密钥存在项目根目录的
.env文件中:BREEZOMETER_API_KEY=你的密钥,确保.env不会被提交到版本控制 - 可以添加Laravel缓存(比如
Cache::remember)来缓存瓦片,减少重复API调用,节省配额 - 生产环境建议用CDN缓存瓦片,减轻服务器压力
- 注意Breezometer的API调用限制,代理请求会消耗你的配额
内容的提问来源于stack exchange,提问作者naman
相关产品推荐
相关产品推荐

