You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决React应用调用newsapi.org时的CORS跨域问题?

React + Redux API调用遇到CORS跨域问题,仅客户端如何解决?

我正尝试在React应用中通过Redux的actions与reducers调用API,但浏览器出现了CORS跨域问题。由于我无法访问该API的内部配置,想了解是否可以仅通过客户端解决此问题,恳请各位提供帮助。

相关代码

newsActions.js

import * as types from './actionTypes';
const API_KEY = "<Redacted>";
export const getNewsApi = () => {
  debugger;
  return (dispatch, getState) => {
    dispatch({
      type: 'API_REQUEST',
      options: {
        method: 'GET',
        service: 'news',
        mode: 'cors',
        headers:{
          'Access-Control-Allow-Origin':'*'
        },
        endpoint: `https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=${API_KEY}`,
        actionTypes: {
          success: types.GET_NEWS_API_SUCCESS,
          error: types.GET_NEWS_API_ERROR
        }
      }
    });
  }
}

server.js

var express = require('express');
var app = express();
var cors = require('cors');
let __homeglobals = [];
app.use(cors());
app.set("jsonp callback", true);
var server = app.listen(8082, function () {
  var host = server.address().address;
  var port = server.address().port;
  console.log("Example app listening at http://%s:%s", host, port);
});

若需更多信息或有疑问,请在下方留言。谢谢。


解决方案说明

首先得明确:纯前端代码是没办法绕过浏览器的CORS限制的——同源策略是浏览器的安全机制,除非目标API主动配置允许你的域名访问,否则直接从前端发起跨域请求肯定会被拦截。不过你已经有了自己的Node.js Express服务,可以把它改造成请求代理,完美解决这个问题。

步骤1:改造Express代理服务

在你的server.js里添加一个代理路由,让它帮你转发请求到NewsAPI,这样前端请求自己的服务就不存在跨域问题了:

var express = require('express');
var app = express();
var cors = require('cors');
var axios = require('axios'); // 先执行 npm install axios 安装依赖
let __homeglobals = [];

app.use(cors());
app.set("jsonp callback", true);

// 新增代理路由,处理新闻API请求
app.get('/api/news', async (req, res) => {
  try {
    const API_KEY = "<Redacted>"; // 把API Key移到服务端,避免前端暴露
    const targetUrl = `https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=${API_KEY}`;
    const response = await axios.get(targetUrl);
    res.json(response.data);
  } catch (error) {
    res.status(error.response?.status || 500).json({ error: error.message });
  }
});

var server = app.listen(8082, function () {
  var host = server.address().address;
  var port = server.address().port;
  console.log("Example app listening at http://%s:%s", host, port);
});

步骤2:修改Redux Action的请求地址

把原来直接请求NewsAPI的地址,改成请求你的代理服务地址:

import * as types from './actionTypes';
export const getNewsApi = () => {
  return (dispatch, getState) => {
    dispatch({
      type: 'API_REQUEST',
      options: {
        method: 'GET',
        service: 'news',
        // 去掉多余的mode和无效的请求头,现在请求的是同源服务
        endpoint: `http://localhost:8082/api/news`,
        actionTypes: {
          success: types.GET_NEWS_API_SUCCESS,
          error: types.GET_NEWS_API_ERROR
        }
      }
    });
  }
}

为什么之前的配置无效?

你在请求头里加Access-Control-Allow-Origin是搞错了对象——这个头是服务器返回给浏览器的响应头,不是前端发给服务器的请求头,前端设置它完全没用,浏览器会直接忽略。另外mode: 'cors'是浏览器跨域请求的默认模式,设置了也不会改变跨域拦截的结果。

其他可选方案(仅限调试或特殊场景)

  • 浏览器插件临时禁用CORS:比如CORS Unblock这类插件,只能用于本地开发调试,绝对不能用于生产环境。
  • JSONP方式:但NewsAPI不支持JSONP,所以这个方案对你不适用。

内容的提问来源于stack exchange,提问作者Eunicorn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:06:19