Cloudflare Workers调用Google Maps API失败问题求助
解决Cloudflare Workers调用Google Maps Autocomplete API 502错误及缓存实现问题
你的502错误核心原因是调用了Google Maps的非公开内部接口,AutocompletionService.GetPredictionsJson是Google Maps网页JS库使用的私有接口,不支持直接外部调用,必须使用官方公开的Places Autocomplete REST API。同时代码中还有URL构造、KV操作的错误,下面是修正后的完整实现:
修正后的Worker代码
export default { async fetch(request, env) { try { const url = new URL(request.url); // 从查询参数获取搜索关键词,示例请求:https://your-worker-domain.com/?input=London const input = url.searchParams.get('input'); // 可选:获取自定义参数,默认值适配你的需求 const language = url.searchParams.get('language') || 'en-GB'; const components = url.searchParams.get('components') || 'country:GB'; if (!input) { return new Response("缺少必填参数 'input'(示例:?input=London)", { status: 400, headers: { 'Content-Type': 'text/plain; charset=utf-8' } }); } if (request.method === "GET") { // 组合缓存键,确保不同参数的请求缓存独立 const cacheKey = `autocomplete_${encodeURIComponent(input)}_${language}_${components}`; // 检查KV缓存(绑定KV命名空间后直接使用env.MAPS,无需namespace参数) const cachedResponse = await env.MAPS.get(cacheKey, { type: 'text' }); if (cachedResponse) { return new Response(cachedResponse, { status: 200, headers: { 'Content-Type': 'application/json', 'X-Cache': 'HIT' } }); } else { // 构造官方公开的Google Places Autocomplete API请求 const googleApiUrl = new URL('https://maps.googleapis.com/maps/api/place/autocomplete/json'); googleApiUrl.searchParams.set('input', input); googleApiUrl.searchParams.set('key', env.GOOGLE_MAPS_API_KEY); // 从环境变量读取API密钥 googleApiUrl.searchParams.set('language', language); googleApiUrl.searchParams.set('components', components); googleApiUrl.searchParams.set('types', 'geocode'); // 可选:限制结果类型 // 发送请求到Google API,添加合规请求头 const googleResponse = await fetch(googleApiUrl.toString(), { headers: { 'User-Agent': 'Cloudflare Worker Proxy', 'Accept': 'application/json' } }); if (!googleResponse.ok) { const errorText = await googleResponse.text(); return new Response( `Google API请求失败:${errorText}`, { status: googleResponse.status, headers: { 'Content-Type': 'text/plain; charset=utf-8' } } ); } const responseText = await googleResponse.text(); // 将响应存入KV,设置7天过期时间(可根据需求调整) await env.MAPS.put(cacheKey, responseText, { expirationTtl: 604800 // 单位:秒 }); // 返回Google API的响应,保留原响应头并标记缓存状态 return new Response(responseText, { status: 200, headers: { ...Object.fromEntries(googleResponse.headers.entries()), 'X-Cache': 'MISS' } }); } } else { return new Response("不支持的请求方法", { status: 405 }); } } catch (e) { return new Response(`服务器错误:${e.stack}`, { status: 500, headers: { 'Content-Type': 'text/plain; charset=utf-8' } }); } }, };
关键修改说明
- 切换公开API:使用官方公开的
/maps/api/place/autocomplete/json接口,需先在Google Cloud控制台启用Places API并生成合法密钥。 - URL构造优化:通过
URL对象拼接参数,避免字符串替换导致的格式错误。 - KV操作修正:移除错误的
namespace参数,Worker绑定KV命名空间后直接使用env.MAPS即可(绑定步骤:在Cloudflare Workers控制台「变量」页添加KV命名空间绑定,变量名设为MAPS)。 - 缓存键设计:用
input+language+components组合作为缓存键,避免不同参数的请求共用缓存。 - 安全存储密钥:将Google API密钥存入Worker环境变量
GOOGLE_MAPS_API_KEY,避免硬编码泄露。 - 错误处理增强:捕获并返回Google API的错误详情,便于调试。
部署注意事项
- 在Google Cloud控制台启用Places API,并为API密钥设置使用范围(限制为Cloudflare Workers的IP或域名)。
- 在Cloudflare Workers控制台:
- 创建KV命名空间(如
MAPS_CACHE)。 - 添加KV绑定:变量名
MAPS,选择创建好的KV命名空间。 - 添加环境变量
GOOGLE_MAPS_API_KEY,值为你的Google API密钥。
- 创建KV命名空间(如
- 测试请求:访问
https://your-worker-domain.com/?input=London,第一次请求返回X-Cache: MISS,第二次返回X-Cache: HIT。
内容的提问来源于stack exchange,提问作者Sojin Samuel
相关产品推荐
相关产品推荐

