You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 06:24:35