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

Chrome扩展Manifest V3中使用Google Maps API获取经纬度的问题

解决Chrome扩展Manifest V3中加载Google Maps API的CSP错误并实现城市经纬度获取功能

问题根源

Manifest V3对扩展的内容安全策略(CSP)限制更严格,默认仅允许加载self来源的脚本,直接动态加载Google Maps API脚本会触发CSP报错。

解决方案步骤

1. 修改Manifest.json的CSP配置

在manifest.json中更新content_security_policy字段,将Google Maps域名加入脚本源白名单:

{
  "manifest_version": 3,
  // 其他扩展配置项...
  "content_security_policy": {
    "extension_pages": "script-src 'self' https://maps.googleapis.com; object-src 'self'"
  }
}
  • extension_pages规则针对扩展自身页面(popup、options等)生效
  • 添加https://maps.googleapis.com到script-src,允许加载该域名下的API脚本

2. 修正脚本加载与初始化逻辑

原代码中useEffect同时触发脚本加载和初始化会导致google未定义的错误,调整为仅触发脚本加载,初始化逻辑绑定到脚本加载完成的回调:

const initAutoComplete = () => {
  const input = document.getElementById("search") as HTMLInputElement;
  const autoComplete = new google.maps.places.Autocomplete(input, {
    types: ["(cities)"],
  });
  autoComplete.addListener("place_changed", () => {
    const place = autoComplete.getPlace();
    if (!place.geometry) return;

    const latitude = place.geometry.location?.lat();
    const longitude = place.geometry.location?.lng();
    const city = place.address_components?.find(
      (component) => component.types[0] === "locality"
    )?.long_name;

    if (latitude && longitude && city) {
      setCity(city);
      setLatitude(parseFloat(latitude.toString().slice(0, 9)));
      setLongitude(parseFloat(longitude.toString().slice(0, 9)));
      // 发送数据到background.js
      chrome.runtime.sendMessage({
        type: 'CITY_LOCATION',
        city,
        latitude,
        longitude
      });
    }
  });
};

function loadScript() {
  const scriptSrc = "https://maps.googleapis.com/maps/api/js?key=你的API密钥&libraries=places";
  const existingScript = Array.from(document.head.getElementsByTagName("script"))
    .find(scr => scr.src === scriptSrc);

  if (existingScript) {
    initAutoComplete();
    return;
  }

  const script = document.createElement("script");
  script.src = scriptSrc;
  script.async = true;
  script.defer = true;
  script.onload = initAutoComplete;
  document.head.appendChild(script);
}

useEffect(() => {
  loadScript();
}, []);
  • 优化重复脚本检测逻辑,避免重复加载
  • 确保initAutoComplete仅在Google Maps API脚本加载完成后执行
  • 添加chrome.runtime.sendMessage,将城市和经纬度数据发送到background.js

3. 在Background.js中监听消息

在background.js中添加消息监听,接收popup传来的数据并处理:

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === 'CITY_LOCATION') {
    // 这里可根据需求处理数据,比如存储到chrome.storage或执行其他业务逻辑
    console.log('获取到城市位置:', message.city, message.latitude, message.longitude);
  }
});

额外注意事项

  • 确保你的Google Cloud API密钥已启用Places API,并配置了正确的引用限制(比如绑定你的扩展ID)
  • 替换代码中的你的API密钥为实际有效的密钥

内容的提问来源于stack exchange,提问作者Abdelrahman Rageh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 10:57:15