我尝试访问中型API以获取用户的公开报道列表。但是,当我尝试在客户端访问它时,我收到了CORS错误。这是代码
axios.get(`http://medium.com/@ev/latest`).then((res)=>{
console.log(res.data)
})
.catch((error)=>{
console.log(error)
})
我做了一些研究并找到了github issue,但找不到任何解决方法。有没有办法让这个请求在客户端工作?
答案 0 :(得分:2)
您可以通过CORS代理发出请求来获取https://medium.com/@ev/latest中的HTML - 您自己设置的代理,或者只使用公共开放式CORS代理https://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”问题< / em>在 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);</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,
这是因为即使
JSON.parse
是文字,也始终在回复中尝试responseType
。我们应该确实这样做。
https://medium.com/@ev/latest是HTML,而不是JSON,因此在其上运行JSON.parse
会失败。
这就是为什么这个答案中的第一个片段改为使用Fetch API(你可以用它来获取文本)。
答案 1 :(得分:0)
Medium目前不允许这样做(服务器不会使用Access-Control-Allow-Origin
标头进行响应)。可能是出于安全考虑。
正如您链接的GitHub问题所示,可能的解决方案是通过您的服务器(作为代理)将请求隧道传输到Medium。您可以在服务器上创建一个端点(即http://my-server.com/get-medium/@ev/latest
),该端点将检索所请求的中间页面(在服务器端)并将其返回给客户端。
此问题的评论描述了使用AWS Lambda作为代理服务器的方法 - link