Angular 4直接调用Google Places Web API遭遇CORS问题求解
解决Angular 4调用Google Places自动补全Web Service的CORS问题
这个问题我之前碰到过,核心原因很明确:Google Places Web Service是为服务器端调用设计的,它没有配置允许前端跨域的CORS响应头,所以浏览器的同源策略会直接拦截你的请求响应,这不是Angular代码的问题,是浏览器的安全机制限制。
下面给你两个实用的解决方案,覆盖开发和生产环境:
方案1:开发环境用Angular CLI代理(仅开发阶段)
如果你只是在本地开发测试,可以用Angular CLI的代理功能绕过CORS限制:
- 在项目根目录创建
proxy.conf.json文件,内容如下:
{ "/api/places": { "target": "https://maps.googleapis.com/maps/api/place", "secure": true, "changeOrigin": true, "pathRewrite": { "^/api/places": "" } } }
- 修改
.angular-cli.json(Angular 4的配置文件)里的serve配置,添加代理路径:
"serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "your-project-name:build", "proxyConfig": "proxy.conf.json" } }
- 修改你的Angular请求代码,指向代理后的路径:
this.http.get('/api/places/autocomplete/json?input=Vict&types=geocode&key=YOUR_API_KEY') .subscribe(response => { console.log(response.json()); });
重启Angular开发服务器后,请求就会被CLI代理转发到Google的API,避开CORS限制。
方案2:后端代理(生产环境必用)
生产环境下,Angular项目是静态文件,没法用CLI代理,必须自己搭建一个后端服务中转请求——后端请求不受浏览器同源策略限制,完美解决跨域问题,还能保护你的API Key不被前端暴露。
举个Node.js(Express)的简单示例:
- 搭建一个Express服务,写一个中转路由:
const express = require('express'); const axios = require('axios'); const app = express(); // 建议把API Key存在后端环境变量里,不要暴露给前端 const GOOGLE_API_KEY = process.env.GOOGLE_PLACES_KEY; app.get('/api/places/autocomplete', async (req, res) => { try { const { input, types } = req.query; const response = await axios.get('https://maps.googleapis.com/maps/api/place/autocomplete/json', { params: { input, types, key: GOOGLE_API_KEY } }); res.send(response.data); } catch (error) { res.status(error.response.status).send(error.response.data); } }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => console.log(`Proxy server running on port ${PORT}`));
- 修改Angular代码,请求自己的后端接口:
this.http.get('https://your-backend-domain/api/places/autocomplete?input=Vict&types=geocode') .subscribe(response => { console.log(response.json()); });
关键注意事项:
- 把Google API Key存在后端环境变量里,不要在前端代码中暴露,避免被恶意盗用;
- 在Google Cloud控制台给你的服务器端API Key设置访问限制(比如只允许你的后端IP或域名调用),进一步提升安全性。
为什么不能直接前端调用?
Google Places Web Service的官方文档明确说明,该服务是为服务器端应用设计的,不支持前端直接跨域请求,所以没有配置CORS响应头,浏览器会严格拦截这类跨域请求,没有绕过的办法(除了通过代理中转)。
内容的提问来源于stack exchange,提问作者Aditya Vashishtha
相关产品推荐
相关产品推荐

