Node.js如何通过Google Place Photo API安全获取地点图片
Google Place Photos API 图片获取方案
响应逻辑说明
Google Place Photos API 不会返回JSON格式的图片地址,请求成功后会先返回302重定向响应,自动跳转到实际托管图片的CDN地址。你当前拿到的200响应是fetch默认跟随重定向后的结果,响应体本身就是image/jpeg格式的二进制图片数据,不是结构化JSON。
你打印的响应对象里有两个可直接提取的信息:
response.url:重定向后的真实图片CDN临时地址- 响应body:图片二进制流数据
前端直接获取图片的实现(仅适合本地测试,会暴露API密钥)
如果仅做本地调试,可以通过两种方式从响应拿到可用的图片地址:
直接读取重定向后的临时地址
async function getImageOfPlace(photoReference){ try{ const response = await fetch(`https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photo_reference=${photoReference}&key=${apiKey}`); // 直接拿到重定向后的临时CDN地址 const tempImageUrl = response.url; document.querySelector('img').src = tempImageUrl; }catch(e){ console.error('获取图片失败', e); } }注意:这个地址是Google动态生成的,有缓存有效期,不能做长期存储。
转Blob生成本地临时地址
如果你需要对图片做二次处理(比如本地裁剪、上传到自己的存储),可以把响应转成Blob对象生成本地访问地址:async function getImageOfPlace(photoReference){ try{ const response = await fetch(`https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photo_reference=${photoReference}&key=${apiKey}`); const imageBlob = await response.blob(); const localImageUrl = URL.createObjectURL(imageBlob); document.querySelector('img').src = localImageUrl; // 图片使用完成后调用释放内存 // URL.revokeObjectURL(localImageUrl); }catch(e){ console.error('获取图片失败', e); } }
你提到的直接把带密钥的API地址放到img标签src的写法确实可以正常加载图片,但绝对不能在生产环境使用——前端代码里的API密钥可以被任意用户通过查看源码、抓包拿到,极易被盗用产生超额账单。哪怕给密钥配置域名白名单,也可以通过伪造请求Referer头绕过限制,没有实际安全防护作用。
生产环境安全方案(后端代理,完全隐藏密钥)
要彻底避免密钥泄露,所有携带Google API密钥的请求必须放到服务端发起,前端只和你自己的后端服务交互,流程如下:
- 前端拿到
photo_reference参数后,请求自己的后端接口,比如/api/place/image?photo_reference=xxx - 后端服务收到请求后,在服务端拼接Google API密钥,向Place Photos接口发起请求,自动跟随重定向拿到图片二进制数据
- 后端直接把图片二进制流返回给前端,或者把拿到的临时CDN地址返回给前端使用
- 前端拿到后端返回的结果后正常加载图片即可
这种方案下Google API密钥全程只存储在服务端环境,完全不会暴露给公网用户,不存在被盗用的风险。
额外建议:你可以在后端代理层加上缓存逻辑,相同
photo_reference的图片请求可以缓存到你自己的对象存储或者CDN上,进一步减少API调用次数,降低成本。
内容的提问来源于stack exchange,提问作者Johhnny
相关产品推荐
相关产品推荐

