尝试从客户端访问 API 中的 public 个故事时出错
Error while trying to access public stories from Medium API on client side
我正在尝试访问 Medium 的 API 以获取用户的 public 故事列表。但是,当我尝试在客户端访问它时出现 CORS 错误。这是代码
axios.get(`http://medium.com/@ev/latest`).then((res)=>{
console.log(res.data)
})
.catch((error)=>{
console.log(error)
})
我做了一些研究并发现了这个 github issue,但找不到任何解决方法。有什么方法可以让这个请求在客户端工作吗?
Medium 目前不允许这样做(那里的服务器不响应 Access-Control-Allow-Origin
header)。可能是出于安全考虑。
正如您链接到的 GitHub 问题中所建议的那样,一个可能的解决方案是通过您的服务器(作为代理)将请求传送到 Medium。您可以在您的服务器上创建一个端点(即 http://my-server.com/get-medium/@ev/latest
),它将检索请求的媒体页面(在服务器端)并将 return 它发送到客户端。
这个问题的评论描述了一种使用 AWS Lambda 作为代理服务器的方法 - link
您可以从 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/ 获得 HTML。以下是使用标准 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”问题在 .
的答案中
顺便说一句,如果你想要 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:
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.
虽然解决这个问题很简单:只需首先在客户端代码中将响应作为文本处理,然后从开头删除 ])}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 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.
而 https://medium.com/@ev/latest 是 HTML,而不是 JSON,因此 运行ning JSON.parse
将失败。
这就是为什么此答案中的第一个片段使用 Fetch API 代替(您可以用它取回文本)。
我正在尝试访问 Medium 的 API 以获取用户的 public 故事列表。但是,当我尝试在客户端访问它时出现 CORS 错误。这是代码
axios.get(`http://medium.com/@ev/latest`).then((res)=>{
console.log(res.data)
})
.catch((error)=>{
console.log(error)
})
我做了一些研究并发现了这个 github issue,但找不到任何解决方法。有什么方法可以让这个请求在客户端工作吗?
Medium 目前不允许这样做(那里的服务器不响应 Access-Control-Allow-Origin
header)。可能是出于安全考虑。
正如您链接到的 GitHub 问题中所建议的那样,一个可能的解决方案是通过您的服务器(作为代理)将请求传送到 Medium。您可以在您的服务器上创建一个端点(即 http://my-server.com/get-medium/@ev/latest
),它将检索请求的媒体页面(在服务器端)并将 return 它发送到客户端。
这个问题的评论描述了一种使用 AWS Lambda 作为代理服务器的方法 - link
您可以从 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/ 获得 HTML。以下是使用标准 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”问题在
顺便说一句,如果你想要 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:
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.
虽然解决这个问题很简单:只需首先在客户端代码中将响应作为文本处理,然后从开头删除 ])}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 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.
而 https://medium.com/@ev/latest 是 HTML,而不是 JSON,因此 运行ning JSON.parse
将失败。
这就是为什么此答案中的第一个片段使用 Fetch API 代替(您可以用它取回文本)。