如何正确调用此 api 并使用 fetch 从 api 获取新闻 [重复]

Posted

技术标签:

【中文标题】如何正确调用此 api 并使用 fetch 从 api 获取新闻 [重复]【英文标题】:How can I make this api call correctly and get the news from the api using fetch [duplicate] 【发布时间】:2020-10-29 10:56:30 【问题描述】:

注意:为了保护隐私,api Key 是伪造的。

const url = 'http://newsapi.org/v2/everything?' +
          'q=platformer&' +
          'apiKey=3ce15c4d1fd3485cbcf17879bab498db';

async function getNews() 
    const response = await fetch(url);
    const data = await response.json();
    console.log(data);


getNews()

问题是当我运行这个 javascript 代码时,我得到了这个错误:

CORS 策略已阻止从源“null”访问“http://newsapi.org/v2/everything?q=platformer&apiKey=3ce15c4d1fd3485cbcf17879bab498db”获取:无“访问控制-请求的资源上存在 Allow-Origin' 标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

基本上我想从这个 newsapi.org 中提取新闻并在控制台中查看数据。

【问题讨论】:

由于网站的 CORS 政策,您无法从其他域获取数据。一个解决方案是在 Node.js 中使用 axios 确实,在服务器端发出请求会更好。因为您的 API 密钥是私有的。它不应与任何人共享,因此不应嵌入到您的前端代码中。这就是 API 未启用 CORS 的原因。 Docs "您可以通过以下三种方式之一将您的 API 密钥附加到请求中:- apiKey 查询字符串参数。- X-Api-Key HTTP 标头。- 授权 HTTP 标头。我们强烈推荐后者 2 以便其他人在日志或请求嗅探中看不到您的 API 密钥。” 【参考方案1】:

简而言之,您可以使用 CORS 代理

您的问题已经回答了here,它提供了更大的 CORS 代理说明和演练。


NewsApi.org 也有一个公认的答案,特别是更简短的here。

摘录:

您需要一个 CORS 代理

const proxyUrl = "https://cors-anywhere.herokuapp.com/"
const qInTitle = "";
const from = "";
const apiKey = "";
const url = `$proxyUrlhttps://newsapi.org/v2/everything?qInTitle=$qInTitle&from=$fromlanguage=en&apiKey=$apiKey`;
const request = new Request(url);

fetch(request)
  .then(response => response.json())
  .then((news) => 
    console.log(news);
  )
  .catch(error => 
    console.log(error);
  );

另外,如果您需要了解更多关于 CORS 的一般信息,这里有一篇非常详尽的文章:

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

【讨论】:

正如上面的评论所暗示的,将他们的 API 密钥公开给应该保密的服务是不好的做法。 @Bren 这可能是真的(我绝对同意@blex!),但如果 OP 不要求最佳实践,提供有关使用 CORS 代理或其他可行解决方法的答案可能仍然证明对 OP 的目标有所帮助。 我收到 426 升级错误:newsapi.js:20 GET cors-anywhere.herokuapp.com/https://newsapi.org/v2/… 426(需要升级)【参考方案2】:

News API的错误信息提供了提示:

开发者计划不允许来自浏览器的请求,除非来自本地主机

假设您确实使用本地开发服务器(如this one)运行应用程序,将浏览器指向http://localhost:8080/ 而不是http://127.0.0.1:8080/ 就可以了:

下面的代码示例(使用网络服务器在本地运行):

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <h1>News</h1>

  <button id="btn-get">Get News</button>
  <div id="news-container"></div>
  <script>
    const url = `https://newsapi.org/v2/everything?q=bitcoin&apiKey=API_KEY`

    const newsContainer = document.getElementById('news-container')

    function fetchNews(url) 
      return fetch(url)
        .then(res => res.json())
    

    document.getElementById('btn-get').addEventListener('click', () => 
      fetchNews(url)
        .then(articles => newsContainer.textContent = JSON.stringify(articles))
    )

  </script>

</body>

</html>

【讨论】:

当我在 localhost 上运行但我的网站托管在 university.edu 上时,这确实有效

以上是关于如何正确调用此 api 并使用 fetch 从 api 获取新闻 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 React 中使用 fetch 正确处理来自 REST API 的数据对象

如何从“await fetch()”解析 Promise?

从画布正确获取信息并通过带有 node-fetch 的 webhook 将信息发送到 discord 时出现问题

如何在javascript fetch中存储访问令牌并传递给下一个api调用

从 fetch() 返回 html 并显示给用户

使用 Click 调用 Fetch