如何使用 https://newsapi.org/ 克服 CORS 问题

IT技术 javascript reactjs redux cors react-redux
2021-05-16 15:06:58

我正在尝试通过我的 React 应用程序中的 Redux 操作和减速器进行 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);
});

如果您需要更多信息或有任何疑问,请在下方评论。

谢谢你。

2个回答

您可以通过从源(Web 服务器)代理到 API 服务器来解决跨源问题。

更改客户端代码中的调用以将请求发送到/api/whatever(故意缺少方案、主机和端口,因此它使用为页面提供服务的那个)。从客户端的角度来看,这不再是对不同主机的请求。

我想在您调度的操作中,这将对应于更改endpoint属性:

endpoint: `/api/top-headlines?country=us&category=business&apiKey=${API_KEY}`

然后在您的 Web 服务器中设置基于路径的代理以匹配以 开头的路由/api并将它们代理到https://newsapi.org/v2. 例如,使用http-proxy-middleware

var proxy = require('http-proxy-middleware');

app.use('/api', proxy({target: 'https://newsapi.org/v2'}));

请注意,“Access-Control-Allow-Origin”标头是由服务器而不是客户端设置的,因此在您的示例中它没有做任何有用的事情。

我想知道我是否可以从客户端解决这个问题,因为我在内部没有任何访问 API 的权限。

不幸的是你不能;请求背后的服务器必须为 CORS 设置正确的 CORS 标头才能工作(您不能从客户端请求中设置它)。这是由浏览器本身强制执行的,而不是您可以从客户端代码解决的问题。

自 MDN

出于安全原因,浏览器会限制从脚本内发起的跨域 HTTP 请求。例如,XMLHttpRequest 和 Fetch API 遵循同源策略。这意味着使用这些 API 的 Web 应用程序只能从加载应用程序的同一域中请求 HTTP 资源,除非使用 CORS 标头。

在这种情况下,该 API 似乎旨在从服务器使用,而不是直接从浏览器使用。