我可以点击这个端点,http://catfacts-api.appspot.com/api/facts?number=99通过邮递员返回JSON
此外,我正在使用CreateReact应用程序,希望避免设置任何服务器配置
在我的客户机代码中,我试图使用fetch执行相同的操作,但我得到了错误:
请求的服务器上不存在“Access Control Allow Origin”标头
资源起源’http://localhost:3000因此,”不允许”
通道如果不透明的响应满足您的需要,请设置请求的
模式设置为“无cors”,以获取禁用cors的资源
因此,我试图将一个对象传递给我的Fetch,它将禁用CORS,如下所示:
fetch('http://catfacts-api.appspot.com/api/facts?number=99“,{模式:'无cors'})
.then(blob=>;blob.json())
。然后(数据=>{
控制台.表格(数据);
返回数据;
})
.catch(e=>{
控制台日志(e);
返回e;
});
有趣的是,我得到的错误实际上是这个函数的语法错误。我不确定我的实际fetch是否被破坏,因为当我删除{mode:’no cors’}对象,并为其提供一个不同的URL时,它工作得很好
我还尝试在对象{mode:'opaque'}中传递,但这会返回上面的原始错误
我相信我所需要做的就是禁用CORS。。我错过了什么
模式:“无cors”无法神奇地使事情正常运行。事实上,这会让事情变得更糟,因为它的一个效果是告诉浏览器,“阻止我的前端JavaScript代码在任何情况下都看不到响应体和标题的内容。”当然,你永远不会想要这样
来自前端JavaScript的跨源请求的情况是,默认情况下,浏览器会阻止前端代码访问跨源的资源。如果响应中有访问控制允许源代码,则浏览器会放松该阻塞并允许您的代码访问响应
但是,如果一个站点在其响应中不发送访问控制允许源站,则前端代码无法直接访问该站点的响应。特别是,您无法通过指定模式:“no cors”来修复它(事实上,这将确保您的前端代码无法访问响应内容)
但是,有一件事将起作用:如果您通过CORS代理发送请求
您还可以使用5个命令,在2-3分钟内轻松地将自己的代理部署到Heroku:
git克隆https://github.com/Rob--W/cors-anywhere.git
cd-cors随处可见/
npm安装
赫罗库创造
git推送heroku主机
运行这些命令后,您将得到自己的CORS Anywhere服务器,例如,https://cryptic-headland-94862.herokuapp.com/
在请求URL前面加上代理URL;例如:
https://cryptic-headland-94862.herokuapp.com/https://example.com
将代理URL添加为前缀会导致通过代理发出请求,这:
- 将请求转发到
https://example.com - 从
https://example.com - 将
访问控制允许原点标题添加到响应中 - 将带有添加的头的响应传递回请求的前端代码
然后浏览器允许前端代码访问响应,因为带有访问控制允许原点的响应是浏览器看到的
即使请求触发浏览器执行CORS飞行前选项请求,这也会起作用,因为在这种情况下,代理还会发回飞行前成功所需的访问控制允许标头和访问控制允许方法标头
我可以点击这个端点,
http://catfacts-api.appspot.com/api/facts?number=99通过邮递员
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS 解释了为什么即使你可以通过邮递员访问回复,浏览器不允许您从web应用程序中运行的前端JavaScript代码跨源访问响应,除非响应包含access Control Allow originresponse头
http://catfacts-api.appspot.com/api/facts?number=99 没有Access Control Allow Origin响应头,因此前端代码无法跨源访问响应
您的浏览器可以获得良好的响应,您可以在Postman甚至浏览器开发工具中看到响应,但这并不意味着浏览器会将其公开给您的代码。它们不会,因为它没有访问控制Allow Origin响应头。因此,您必须使用代理来获取它
代理向该站点发出请求,获取响应,添加Access Control Allow Origin响应头和所需的任何其他CORS头,然后将其传递回请求代码。添加了Access Control Allow Origin标题的响应是浏览器看到的,因此浏览器允许前端代码实际访问响应
因此,我试图将一个对象传递给我的Fetch,这将禁用CORS
你不想那样做。要明确的是,当你说你想“禁用CORS”时,似乎你实际上是指你想禁用同一原产地策略。CORS本身实际上就是这样做的一种方式——CORS是放松同一原产地政策的一种方式,而不是限制它的一种方式
但无论如何,您确实可以在本地环境中设置浏览器运行时标志以禁用安全性并不安全地运行,或者您可以在本地安装浏览器扩展以绕过同源策略,但所做的只是在本地为您改变情况
无论您在本地更改了什么,尝试使用您的应用程序的任何其他人仍将运行相同的源代码策略,并且您无法为您的应用程序的其他用户禁用该策略
在实践中,你很可能永远都不想使用模式:“无COR”,除非在少数有限的情况下,即使这样,也只有在你确切知道自己在做什么以及效果是什么的情况下。这是因为设置模式:“no cors”实际上对浏览器说的是,“在任何情况下都阻止我的前端JavaScript代码查看响应正文和标题的内容。”在大多数情况下,这显然不是您想要的
P> > < > 要考虑使用模式:“没有CORS”,请参阅的答案:对于不透明的响应有什么限制?细节。其要点是:
-
在有限的情况下,当您使用JavaScript将另一来源的内容放入
<;脚本>,<;link rel=样式表>,<;img>,<;视频>,<;音频>,<;对象>,<;嵌入>,或<;iframe>element(这是因为允许跨源嵌入资源),但出于某种原因,您不希望/不能仅通过让文档的标记将资源URL用作元素的href或src属性来实现这一点 -
当您只想缓存资源时。正如中提到的不透明响应有哪些限制?中所述,在实践中,适用的场景是当您使用服务工作者时,在这种情况下,相关的API是缓存存储API
但即使在那些有限的情况下,也有一些重要的问题需要注意请参见中的答案,不透明回答有哪些限制?了解详细信息
我还尝试在对象
{mode:'opaque'}
没有模式:“不透明”请求模式-不透明只是响应的一个属性,浏览器对使用无cors模式发送的请求的响应设置该不透明属性
但是顺便说一句,不透明这个词是一个非常明确的信号,表明了你最终得到的反应的性质:“不透明”意味着你看不见它