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
相关产品推荐
相关产品推荐

