纯React应用调用Yahoo Finance API遭CORS拦截问题求解
解决纯React应用调用Yahoo Finance API的CORS问题
首先纠正你之前的错误配置:Access-Control-Allow-Origin是服务器返回的响应头,前端在请求头里设置这个字段不仅没用,还会触发浏览器的预检OPTIONS请求,反而加剧CORS报错,必须删掉这个请求头配置。
针对你纯React无后端的场景,提供以下可行方案:
方案1:利用React开发服务器代理 + 部署平台重写规则
开发阶段
在项目根目录的package.json中添加代理配置:
{ "name": "your-react-app", "proxy": "https://query1.finance.yahoo.com", // 其他原有配置... }
修改fetch调用,使用相对路径:
fetch('/v8/finance/chart/RCF.BO') .then(res => res.json()) .then(data => console.log(data)) .catch(err => console.error(err))
这样React开发服务器会自动将请求转发到目标API,绕过浏览器的CORS检查。
部署阶段
根据你使用的部署平台配置重写规则:
- Netlify:在项目根目录创建
_redirects文件,添加以下内容:/v8/finance/chart/* https://query1.finance.yahoo.com/v8/finance/chart/:splat 200 - Vercel:在项目根目录创建
vercel.json文件,添加以下配置:{ "rewrites": [ { "source": "/v8/finance/chart/(.*)", "destination": "https://query1.finance.yahoo.com/v8/finance/chart/$1" } ] }
部署后,应用的相对路径请求会被平台转发到目标API,避免CORS问题。
方案2:自建轻量CORS代理
如果不想依赖平台重写规则,可以用Node.js搭建一个极简的CORS代理,部署到免费平台(如Vercel/Netlify的Serverless函数):
示例Vercel Serverless函数(api/proxy.js)
import { createProxyMiddleware } from 'http-proxy-middleware'; export default function handler(req, res) { const proxy = createProxyMiddleware({ target: 'https://query1.finance.yahoo.com', changeOrigin: true, pathRewrite: { '^/api/proxy': '', // 去掉路径中的/api/proxy前缀 }, }); proxy(req, res); }
然后修改fetch调用:
fetch('/api/proxy/v8/finance/chart/RCF.BO') .then(res => res.json()) .then(data => console.log(data))
这个代理会转发请求并添加必要的CORS响应头,让浏览器接受返回数据。
方案3:尝试JSONP(仅当API支持时)
如果Yahoo Finance的API支持JSONP,可以用这种方式绕过CORS:
function fetchStockData(symbol) { return new Promise((resolve, reject) => { const script = document.createElement('script'); const callbackName = `yahooFinanceCallback_${Date.now()}`; window[callbackName] = function(data) { resolve(data); delete window[callbackName]; document.body.removeChild(script); }; script.src = `https://query1.finance.yahoo.com/v8/finance/chart/${symbol}.BO?callback=${callbackName}`; script.onerror = () => { reject(new Error('请求失败')); delete window[callbackName]; document.body.removeChild(script); }; document.body.appendChild(script); }); } // 使用示例 fetchStockData('RCF') .then(data => console.log(data)) .catch(err => console.error(err))
注意:需要测试该API是否支持JSONP回调参数,若不支持则此方案无效。
内容的提问来源于stack exchange,提问作者Kanchan Bharti
相关产品推荐
相关产品推荐

