mode: 'no-cors'
不会神奇地让事情顺利进行。事实上,它使事情变得更糟,因为它的一个效果是告诉浏览器,“阻止我的前端JavaScript代码在任何情况下都看不到响应正文和标头的内容。当然,你永远都不想这样。
来自前端 JavaScript 的跨源请求所发生的情况是,默认情况下,浏览器会阻止前端代码跨源访问资源。如果在响应中,则浏览器会放宽该阻止并允许您的代码访问响应。Access-Control-Allow-Origin
但是,如果站点在其响应中不发送任何内容,则您的前端代码无法直接访问来自该站点的响应。特别是,您无法通过指定来修复它(实际上,这将确保您的前端代码无法访问响应内容)。Access-Control-Allow-Origin
mode: 'no-cors'
但是,有一件事是可行的:如果您通过CORS代理发送请求。
您还可以在短短2-3分钟内轻松地将自己的代理部署到Heroku,只需5个命令:
git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master
运行这些命令后,您最终将拥有自己的 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
- 将标头添加到响应中。
Access-Control-Allow-Origin
- 将该响应(添加了该标头)传递回请求的前端代码。
然后,浏览器允许前端代码访问响应,因为带有响应标头的响应是浏览器看到的。Access-Control-Allow-Origin
即使请求是触发浏览器执行 CORS 预检请求的请求,这也有效,因为在这种情况下,代理还会发回使预检成功所需的 和 标头。OPTIONS
Access-Control-Allow-Headers
Access-Control-Allow-Methods
我可以通过Postman点击这个端点http://catfacts-api.appspot.com/api/facts?number=99
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS 解释了为什么即使您可以使用Postman访问响应,浏览器也不会允许您从Web应用程序中运行的前端JavaScript代码访问跨源响应,除非响应包含响应标头。Access-Control-Allow-Origin
http://catfacts-api.appspot.com/api/facts?number=99 没有响应标头,因此前端代码无法访问跨源响应。Access-Control-Allow-Origin
您的浏览器可以很好地获得响应,您可以在Postman甚至浏览器开发工具中看到它 - 但这并不意味着浏览器会将其公开给您的代码。他们不会,因为它没有响应标头。因此,您必须改用代理来获取它。Access-Control-Allow-Origin
代理向该站点发出请求,获取响应,添加响应标头和所需的任何其他 CORS 标头,然后将其传递回请求代码。添加标头的响应是浏览器看到的,因此浏览器允许前端代码实际访问响应。Access-Control-Allow-Origin
Access-Control-Allow-Origin
所以我正在尝试传入一个对象,到我的 Fetch,这将禁用 CORS
你不想那样做。需要明确的是,当您说要“禁用 CORS”时,似乎您实际上意味着要禁用同源策略。CORS本身实际上是一种做到这一点的方法 - CORS是一种放松同源策略的方法,而不是限制它的方法。
但无论如何,在本地环境中,您可以确实提供浏览器运行时标志以禁用安全性并不安全地运行,或者您可以在本地安装浏览器扩展以绕过同源策略,但这样做只是在本地为您改变情况。
无论你在本地更改了什么,尝试使用你的应用的任何其他人仍然会遇到同源策略,并且你无法为应用的其他用户禁用该策略。
你很可能永远不想使用模式:除了在少数有限的情况下,在实践中“no-cors”
,即使这样,也只有在你确切地知道你在做什么以及效果是什么的情况下。这是因为设置实际上对浏览器说的是,“阻止我的前端JavaScript代码在任何情况下查看响应正文和标头的内容。在大多数情况下,这显然不是你想要的。mode: 'no-cors'
至于您希望考虑使用 的情况,请参阅不透明响应的哪些限制?中的答案,了解详细信息。它的要点是:mode: 'no-cors'
-
在有限的情况下,当您使用 JavaScript 将来自另一个源的内容放入 、 、 、 或元素中时(这很有效,因为允许跨源嵌入资源)—但由于某种原因,您不希望/不能仅仅通过让文档的标记使用资源 URL 作为元素的 or 属性来做到这一点。<script>
<link rel=stylesheet>
<img>
<video>
<audio>
<object>
<embed>
<iframe>
href
src
-
当您唯一要对资源执行的操作是缓存它时。正如在不透明响应适用哪些限制?中所述,实际上,该方案适用于使用服务工作线程的情况,在这种情况下,相关的 API 是缓存存储 API。
但是,即使在这些有限的情况下,也有一些重要的事情需要注意;有关详细信息,请参阅哪些限制适用于不透明响应的答案?。
我也尝试过传递对象{ mode: 'opaque'}
没有请求模式 - 只是响应的一个属性,浏览器在以模式发送的请求的响应上设置该不透明属性。'opaque'
opaque
no-cors
但顺便说一句,不透明这个词是一个非常明确的信号,表明你最终得到的响应的性质:“不透明”意味着你看不到它的任何细节;它阻止你看到。