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 ifresponseType
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/