React调用Google Maps API获取照片引用时遇CORS错误
React项目中Google Maps Places API照片引用获取失败(CORS问题)
我在React项目中使用Google Maps API的Places、Autocomplete及Geocoding功能,地理编码功能运行正常,但获取照片引用的功能无法工作,遇到了CORS跨域拦截。
代码片段
Geocoding组件
import React, { useState, useEffect } from "react"; import axios from "axios"; import GetPhotosReferences from "./GetPhotosReferences"; const Geocoding = ({ destinations }) => { const [placesIds, setPlacesIds] = useState([]); useEffect(() => { destinations.forEach((destination) => { let APP_ID = process.env.REACT_APP_Maps_API_Key; let formatted_address = destination; axios.get(`https://maps.googleapis.com/maps/api/geocode/json?address=${formatted_address}&key=${APP_ID}`).then((res) => { const placeId = res.data.results[0].place_id; setPlacesIds((prevPlacesIds) => [...prevPlacesIds, placeId]); }); }); }, [destinations]); return ( <div> {placesIds.map((placeId, index) => ( <GetPhotosReferences key={placeId} placesId={placeId} /> ))} </div> ); }; export default Geocoding;
GetPhotosReferences组件
import React, { useState, useEffect } from "react"; import axios from "axios"; const GetPhotosReferences = (props) => { let [photos, setPhotos] = useState([]); useEffect(() => { let APP_ID = process.env.REACT_APP_Maps_API_Key; let placeId = props.placesId; console.log(placeId); axios.get(`https://maps.googleapis.com/maps/api/place/details/json?fields=name%2Crating%2Cphotos&place_id=${placeId}&key=${APP_ID}`).then((res) => { const photos = res.data.result.photos; console.log(photos); setPhotos(photos); }); }, [props.placesId]); if (photos === undefined) return; return ( <div className="Rerun flex flex-row gap-1 flex-wrap justify-center pt-4"> {photos.map((photo, index) => ( <img className="hover:opacity-75 transition ease-in-out duration-150" key={index} src={`https://maps.googleapis.com/maps/api/place/photo?maxwidth=400&photoreference=${photo.photo_reference}&key=${process.env.REACT_APP_Maps_API_Key}`} alt={`Place #${index + 1}`} /> ))} </div> ); }; export default GetPhotosReferences;
错误信息
Access to XMLHttpRequest at 'https://maps.googleapis.com/maps/api/place/details/json?fields=name%2Crating%2Cphotos&place_id=ChIJdd4hrwug2EcRmSrV3Vo6llI&key=AIzaSyAdnv5ZQnovFf5auefpDekgUs3R-My0Hpw' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
已尝试的操作
在package.json中设置https://maps.googleapis.com/maps/api为代理,本地环境有效,但部署到Netlify后失效。
解决办法
1. 使用Google Maps JavaScript SDK(推荐)
Google Maps Places API本身不支持浏览器端直接AJAX调用,官方推荐用JavaScript SDK处理跨域:
- 在项目public/index.html中引入SDK:
<script src="https://maps.googleapis.com/maps/api/js?key=%REACT_APP_Maps_API_Key%&libraries=places"></script>
- 修改GetPhotosReferences组件:
import React, { useState, useEffect, useRef } from "react"; const GetPhotosReferences = ({ placesId }) => { const [photos, setPhotos] = useState([]); const serviceRef = useRef(null); useEffect(() => { if (!serviceRef.current) { const div = document.createElement('div'); serviceRef.current = new window.google.maps.places.PlacesService(div); } serviceRef.current.getDetails({ placeId: placesId, fields: ['photos'] }, (place, status) => { if (status === window.google.maps.places.PlacesServiceStatus.OK) { setPhotos(place.photos || []); } else { console.error('获取地点详情失败:', status); } }); }, [placesId]); return ( <div className="Rerun flex flex-row gap-1 flex-wrap justify-center pt-4"> {photos.map((photo, index) => ( <img className="hover:opacity-75 transition ease-in-out duration-150" key={index} src={photo.getUrl({ maxWidth: 400 })} alt={`Place #${index + 1}`} /> ))} </div> ); }; export default GetPhotosReferences;
2. Netlify代理配置
如果不想用SDK,可通过Netlify的重定向规则实现代理:
- 在项目根目录创建
netlify.toml:
[[redirects]] from = "/api/google-places/*" to = "https://maps.googleapis.com/maps/api/place/:splat" status = 200 force = true headers = { Access-Control-Allow-Origin = "*" }
- 修改GetPhotosReferences中的请求地址:
axios.get(`/api/google-places/details/json?fields=name%2Crating%2Cphotos&place_id=${placeId}&key=${APP_ID}`)
3. 关键注意点
- 确保Google Cloud控制台已启用Places API,且API Key设置了正确的HTTP限制(避免密钥泄露)
- create-react-app的package.json代理仅在开发环境生效,部署到生产环境必须用平台自带的代理方案或后端中转
内容的提问来源于stack exchange,提问作者DanyWuj
相关产品推荐
相关产品推荐

