4

我正在尝试访问 Medium 的 API 以获取用户的公共故事列表。但是,当我尝试在客户端访问它时出现 CORS 错误。这是代码

axios.get(`http://medium.com/@ev/latest`).then((res)=>{
  console.log(res.data)
})
.catch((error)=>{
  console.log(error)
})

我做了一些研究,发现了这个github 问题,但找不到任何解决方法。有没有办法让这个请求在客户端工作?

4

3 回答 3

3

您可以从https://medium.com/@ev/latest获取 HTML,方法是通过 CORS 代理(您自己设置的代理或仅使用https://cors等公共开放 CORS 代理)发出请求-anywhere.herokuapp.com/。以下是使用标准 Fetch API 的方法:

fetch("https://cors-anywhere.herokuapp.com/https://medium.com/@ev/latest")
  .then(res => res.text())
  .then(text => document.querySelector("div").innerHTML = text)
  .catch(error => console.log(error))
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<div></div>

有关更多详细信息 - 包括如何在几分钟内在 Heroku 上设置您自己的 CORS 代理,请参阅如何使用 CORS 代理解决“No Access-Control-Allow-Origin header”问题,答案是No 'Access -Control-Allow-Origin' 标头出现在请求的资源上 - 当尝试从 REST API 获取数据时


顺便说一句,如果你想要 JSON,你可以尝试https://medium.com/@ev/latest?format=json但你会发现你得到的实际上不是有效的 JSON;相反,它开始是这样的:

])}while(1);</x>{"success":true,"payload":{"user":{"userId":"268314bb7e7e","name"…

显然这是故意的,根据 Medium 开发人员在其问题跟踪器中的评论

JSON 页面不打算用作读取 API。额外的代码是为了支持我们自己的使用,并且是避免 JSON 劫持的标准技术。

不过,这很容易解决:只需首先在客户端代码中将响应作为文本处理,])}while(1);</x>然后从一开始就去掉它,然后JSON.parse在剩下的部分上运行。

但就使用 Axios 以文本形式获取响应而言,我想您会发现即使您通过 CORS 代理发出请求,它也不会按预期工作;尝试这个:

axios.get('https://cors-anywhere.herokuapp.com/http://medium.com/@ev/latest', {
    responseType: 'text'
  })
  .then(res => console.log(res.data))
  .catch(error => console.log("ERROR"))
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

代码catch很明显,因为即使您指定responseType: 'text'Axios 显然仍然尝试将响应解析为 JSON

这是因为JSON.parse总是在响应中尝试,即使responseType是文本。我们确实应该解决这个问题。

而且https://medium.com/@ev/latest是 HTML,不是 JSON,所以JSON.parse在上面运行会失败。

这就是为什么这个答案中的第一个片段使用 Fetch API 代替(你可以用它取回文本)。

于 2017-12-12T03:52:05.650 回答
1
于 2021-11-26T07:59:36.097 回答
0

目前,Medium 不允许这样做(服务器不响应Access-Control-Allow-Origin标头)。可能是出于安全考虑。

正如您链接到的 GitHub 问题中所建议的那样,一个可能的解决方案是通过您的服务器(作为代理)将请求隧道传输到 Medium。您可以在您的服务器(即http://my-server.com/get-medium/@ev/latest)上创建一个端点,该端点将检索请求的媒体页面(在服务器端)并将其返回给客户端。

此问题的评论描述了一种使用 AWS Lambda 作为代理服务器的方法 -链接

于 2017-12-12T00:34:48.113 回答