AngularJS $resource调用Google Maps Distance API遇CORS错误求助
嘿,我太懂你这种找了一堆资料却碰不上适配场景的糟心感了——尤其是在Cordova里用$resource调用Google API时蹦出来的跨域错误,简直让人头大。
先给你把问题点透:Google Maps Distance API本身并不支持直接从前端(包括Cordova的本地WebView)发起跨域请求,它的响应里默认不会返回Access-Control-Allow-Origin头,所以哪怕你配置了Cordova的白名单,WebView因为遵循浏览器同源策略,还是会直接拦截你的请求。下面给你几个按生产实用性排序的解决方案:
1. 搭建后端代理服务器(最推荐的生产方案)
核心思路是:前端请求你自己的后端服务器,由后端去调用Google Maps Distance API,再把结果返回给前端。因为前端和后端是同源的(比如都是http://localhost:8000),就能完全绕开CORS限制,还能保护你的Google API密钥不被前端暴露。
举个简单的Node.js/Express代理示例:
// 后端Express代码 const express = require('express'); const axios = require('axios'); const app = express(); const PORT = 3000; // 处理前端的距离查询请求 app.get('/api/get-distance', async (req, res) => { const { origin, destination } = req.query; // 建议把API密钥存在后端环境变量里,别硬写在代码里 const apiKey = process.env.GOOGLE_MAPS_API_KEY; try { const response = await axios.get('https://maps.googleapis.com/maps/api/distancematrix/json', { params: { origins: origin, destinations: destination, key: apiKey } }); res.json(response.data); } catch (error) { res.status(500).json({ error: error.message }); } }); app.listen(PORT, () => { console.log(`代理服务器运行在 http://localhost:${PORT}`); });
然后你的前端$resource就改成请求这个代理接口:
// 前端Cordova的工厂函数示例 angular.module('myApp').factory('DistanceService', ['$resource', function($resource) { return $resource('http://localhost:3000/api/get-distance', {}, { get: { method: 'GET' } }); }]);
2. 使用Cordova原生HTTP插件绕开WebView限制
Cordova的WebView会受同源策略约束,但原生代码发起的请求完全不受这个限制。你可以用cordova-plugin-http这个插件,它用原生HTTP请求替代WebView的XMLHttpRequest,天然避开CORS:
# 先安装插件 cordova plugin add cordova-plugin-http
// 前端调用示例 cordovaHTTP.get('https://maps.googleapis.com/maps/api/distancematrix/json', { origins: '北京', destinations: '上海', key: '你的Google API密钥' }, {}, function(response) { // 解析返回的JSON数据 const result = JSON.parse(response.data); console.log(result); }, function(error) { console.error('请求失败:', error); });
这个方案适合不想搭后端的场景,不过记得用Cordova的环境变量插件存储API密钥,别直接写在代码里。
3. 临时测试方案:禁用浏览器跨域限制(仅开发用)
如果你只是本地调试,不想折腾后端或插件,可以临时关闭Chrome的跨域限制:
- 关闭所有Chrome窗口
- 终端运行(Windows):
chrome --disable-web-security --user-data-dir="C:/ChromeDevSession" - 终端运行(Mac):
open -a Google\ Chrome --args --disable-web-security --user-data-dir="/tmp/chrome_dev"
⚠️ 注意:这个方法绝对不能用于生产环境,只是临时调试用!
最后补两个关键提醒:
- 确保在Google Cloud控制台已经启用了Distance Matrix API
- 给你的API密钥设置合理限制(比如绑定Cordova应用的包名、SHA-1指纹),防止被恶意调用
内容的提问来源于stack exchange,提问作者Ezequiel Ramiro

