【问题标题】:Error while trying to access public stories from Medium API on client side尝试从客户端的 Medium API 访问公共故事时出错
【发布时间】:2018-05-25 08:17:26
【问题描述】:

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

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

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

【问题讨论】:

    标签: javascript cors cross-browser axios medium.com


    【解决方案1】:

    使用此Medium API,您可以轻松获取特定用户编写的article_ids 列表(使用他们的user_id)。

    使用端点GET /user/{user_id}/articles

    它将返回一个 JSON 响应,如下所示:

    {
     "associated_articles": [
        "*hash_id_of_article_1*",
        "*hash_id_of_article_2*",
        "*hash_id_of_article_3*",
        .
        .
        .
    ]
    }
    

    然后,您可以使用此article_ids 列表来获取单个文章的信息或内容。像这样:

    注意:article_id 指的是与每个 Medium Story/Article 相关联的唯一哈希 id。您可以在帖子 URL 的末尾看到它。

    基本网址: https://medium2.p.rapidapi.com

    GET /article/{article_id}

    此端点将返回与文章相关的信息,例如标题、副标题、拍手、投票者、标签、主题、作者(user_id)、发布日期等……

    {
      "id": "*article_id*",
      "title": "*article_title*",
      "subtitle": "*article_subtitle*",
      "claps": "*claps_count*",
      "voters": "*voters_count*",
      "published_at": "*date_of_publishing*",
      "word_count": "*word_count*"
      .
      .
      .
    }
    

    GET /article/{article_id}/content

    此端点将返回文章的文本内容。

    {
      "content": "This is the article's textual content. Blah, blah, blah ..."
    }
    

    更详细的解释可以查看这个页面:https://medium.com/p/fcdb1576558a

    文档:https://nishu-jain.medium.com/medium-apis-documentation-3384e2d08667

    用于测试 api:https://rapidapi.com/nishujain1997.19@gmail.com/api/medium2/

    【讨论】:

      【解决方案2】:

      您可以通过 CORS 代理发出请求,从 https://medium.com/@ev/latest 获取 HTML,可以是您自己设置的代理,也可以使用像 https://cors-anywhere.herokuapp.com/ 这样的公共开放 CORS 代理。以下是使用标准 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' header is present on the requested resource—when trying to get data from a REST API 的答案中。


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

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

      显然这是故意的,per a comment from a Medium developer in their issue tracker

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

      不过,这很容易解决:只需首先在客户端代码中将响应作为文本处理,然后从它的开头去掉])}while(1);&lt;/x&gt;,然后在剩下的部分上运行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"))
      &lt;script src="https://unpkg.com/axios/dist/axios.min.js"&gt;&lt;/script&gt;

      代码命中catch,因为显然即使您指定responseType: 'text'Axios apparently still tries the parse the response as JSON

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

      https://medium.com/@ev/latest 是 HTML,而不是 JSON,因此在其上运行 JSON.parse 会失败。

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

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

          猜你喜欢
          • 2016-06-27
          • 1970-01-01
          • 2018-02-21
          • 1970-01-01
          • 2017-12-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多