Chrome可访问的Yahoo Finance API在Angular 2中触发CORS错误
解决Angular调用Yahoo Finance API的CORS错误
咱们先搞清楚为啥会出现这个问题:直接在Chrome地址栏访问或者用Postman调用API时,浏览器不会触发CORS(跨源资源共享)检查,但Angular应用是在浏览器的沙盒环境里运行的,浏览器会严格执行同源策略——当你的前端域名和Yahoo的API域名不一致时,浏览器会要求Yahoo的服务器返回Access-Control-Allow-Origin响应头,允许你的域名访问,而显然Yahoo的这个API没配置这个,所以就报错了。
下面给你几个可行的解决方案,按需选择就行:
方案1:Angular开发环境代理(最推荐,适合本地开发)
Angular自带代理功能,可以把前端的请求转发到Yahoo API,这样就绕过了CORS限制。
- 在项目根目录创建
proxy.conf.json文件,内容如下:{ "/yahoo-finance/*": { "target": "https://query1.finance.yahoo.com", "secure": true, "changeOrigin": true, "pathRewrite": { "^/yahoo-finance": "" } } } - 修改
angular.json里的serve配置,添加proxyConfig:
或者启动项目时直接指定代理文件:"architect": { "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "your-project-name:build", "proxyConfig": "proxy.conf.json" } } }ng serve --proxy-config proxy.conf.json - 现在在Angular里调用API时,把URL改成相对路径:
import { HttpClient } from '@angular/common/http'; constructor(private http: HttpClient) {} fetchStockData() { const apiUrl = '/yahoo-finance/v8/finance/chart/GOOG?range=1y&includePrePost=false&interval=1mo&corsDomain=finance.yahoo.com&.tsrc=finance'; this.http.get(apiUrl).subscribe(data => { console.log('股票数据:', data); }); }
方案2:使用JSONP绕过CORS(如果API支持的话)
Yahoo部分API支持JSONP格式,这种方式不需要服务器配置CORS,直接通过脚本标签加载数据。
- 在你的Angular模块里导入
HttpClientJsonpModule:import { HttpClientModule, HttpClientJsonpModule } from '@angular/common/http'; @NgModule({ imports: [HttpClientModule, HttpClientJsonpModule] }) export class YourModule {} - 在组件里用
jsonp方法调用API,注意要在URL末尾加&callback=JSONP_CALLBACK:import { HttpClient } from '@angular/common/http'; constructor(private http: HttpClient) {} getStockData() { const url = 'https://query1.finance.yahoo.com/v8/finance/chart/GOOG?range=1y&includePrePost=false&interval=1mo&corsDomain=finance.yahoo.com&.tsrc=finance&callback=JSONP_CALLBACK'; this.http.jsonp(url, 'callback').subscribe(data => { console.log('获取到的数据:', data); }); }
方案3:搭建后端代理服务器(适合生产环境)
如果要部署到生产环境,最好自己搭一个后端服务器作为中间层,前端请求自己的后端,后端再转发请求到Yahoo API,这样就不会有CORS问题了。比如用Node.js+Express写个简单的代理:
const express = require('express'); const { createProxyMiddleware } = require('http-proxy-middleware'); const app = express(); // 转发Yahoo Finance请求 app.use('/yahoo-finance', createProxyMiddleware({ target: 'https://query1.finance.yahoo.com', changeOrigin: true, pathRewrite: { '^/yahoo-finance': '' } })); app.listen(3000, () => { console.log('代理服务器运行在http://localhost:3000'); });
然后Angular里调用http://localhost:3000/yahoo-finance/v8/finance/chart/GOOG?xxx即可。
内容的提问来源于stack exchange,提问作者user2515173




