React应用调用Google Places API搜索周边地点时遭遇CORS跨域拦截
跨域报错核心成因排查
- 请求方法配置错误:Google Places Nearby Search REST接口仅支持GET请求,代码中设置为POST方法时,浏览器会自动触发跨域预检请求(OPTIONS),而Google该接口不会响应这类预检请求,直接返回缺失
Access-Control-Allow-Origin响应头的结果,触发浏览器CORS拦截。 - 自定义请求头无效:代码中手动添加的
Content-Type: application/json、Access-Control-Allow-Origin: *属于非必要客户端配置——其中Access-Control-Allow-Origin是服务端返回资源时需要携带的响应头,客户端请求中添加该头没有任何实际作用;且非简单请求的自定义头配置本身就会触发跨域预检流程,进一步提升跨域拦截概率。 - URL拼接逻辑缺陷:代码中拼接API密钥的部分遗漏了
key=参数前缀,即使跨域问题解决,请求也会因鉴权参数缺失返回接口错误。 - React Hook逻辑问题:
setUrl是异步状态更新操作,代码执行到console.log、fetch调用环节时,读取到的仍是更新前的旧url值,并非刚拼接完成的新地址;同时useEffect依赖项中加入了url、placesList,会导致状态变更后反复触发执行,造成无意义的重复请求,甚至陷入请求死循环。
可正常调用的实现方案
- 修正请求基础配置:将请求方法从
POST调整为GET,删除所有手动添加的自定义请求头,Google Places REST接口对符合规范的简单GET请求默认开放跨域访问,无需额外加头。 - 补全请求参数:拼接URL时补全API密钥的参数格式,确保完整请求地址符合接口鉴权要求。
- 优化Hook执行逻辑:仅保留经纬度相关的依赖项,直接在useEffect内部同步拼接完整请求地址,不依赖
url、placesList这类状态变量作为触发条件,避免异步状态导致的读取旧值、重复请求问题。 - 生产环境适配:如果生产环境部署时遇到跨域限制,可通过服务端代理转发接口请求绕开浏览器跨域规则;不要使用
no-cors模式发起请求——该模式下返回的是不透明响应,无法正常读取接口返回的JSON数据。
修正后的参考代码
useEffect(() => { if (!location.lat || !location.lng) return; // 同步拼接完整请求地址,不依赖状态存储临时url const requestUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${location.lat},${location.lng}&radius=2000&key=你的实际API密钥`; fetch(requestUrl) .then(res => res.json()) .then(result => setPlacesList(result.results || [])) .catch(err => console.error('周边地点拉取失败', err)); }, [location.lat, location.lng]);
内容的提问来源于stack exchange,提问作者Helen。
相关产品推荐
相关产品推荐

