Error while trying to access public stories from Medium API on client side

Solution 1:

You can get the HTML from https://medium.com/@ev/latest by making your request through a CORS proxy — either a proxy you set up yourself or else just by using a public open CORS proxy like https://cors-anywhere.herokuapp.com/. Here’s how to do it using the standard 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>

For more details — including how to set up your own CORS proxy on Heroku in just a few minutes, see How to use a CORS proxy to get around “No Access-Control-Allow-Origin header” problems in the answer at No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API.


Incidentally, if instead you want JSON, you can try https://medium.com/@ev/latest?format=json but you’ll find that what you get back isn’t actually valid JSON; instead it starts out like this:

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

Apparently that’s intentional, per a comment from a Medium developer in their issue tracker:

The JSON page is not intended to be used as a read API. The extra code is there to support our own use and is a standard technique to avoid JSON hijacking.

That’s trivial to work around, though: Just first handle the response as text in your client code, and strip out the ])}while(1);</x> from the start of it, and then run JSON.parse on what remains.

But as far as using Axios to get the response as text, I think you’ll find it’s not going to work as expected even if you make the request through a CORS proxy; try this:

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>

The code hits the catch because apparently even when you specify responseType: 'text', Axios apparently still tries the parse the response as JSON:

This is because JSON.parse is always tried in the response, even if responseType is text. We should fix that indeed.

And https://medium.com/@ev/latest is HTML, not JSON, so running JSON.parse on it will fail.

That’s why the first snippet in this answer uses the Fetch API instead (you can get text back with it).

Solution 2:

UPDATE (11th Jan, 2022): I’ve unlisted my APIs due to technical issues. Sorry for any inconvenience.

Using this Medium API, you can easily fetch a list of article_ids written by a particular user (using their user_id).

Use the endpoint GET /user/{user_id}/articles.

It will return a JSON response, something like this:

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

You can then use this list of article_ids to fetch information or content of individual articles. Like this:

Note: article_id refers to the unique hash id associated with every Medium Story/Article. You can see it at the end of post's URL.

Base URL: https://medium2.p.rapidapi.com

GET /article/{article_id}

This endpoint will return information related to article, such as title, subtitle, claps, voters, tags, topics, author (user_id), published date, etc…

{
  "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

This endpoint will return article's textual content.

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

For more detailed explaination, you can check out this page: https://medium.com/p/fcdb1576558a

For the documentation: https://nishu-jain.medium.com/medium-apis-documentation-3384e2d08667

For testing the apis: https://rapidapi.com/[email protected]/api/medium2/