mode: 'no-cors'
不会神奇地使事情起作用。事实上,这让事情变得更糟,因为它的一种效果是告诉浏览器,“在任何情况下都阻止我的前端 JavaScript 代码查看响应正文和标头的内容。” 当然,你永远不想那样。
来自前端 JavaScript 的跨域请求发生的情况是浏览器默认阻止前端代码访问跨域资源。如果Access-Control-Allow-Origin
在响应中,则浏览器会放宽阻止并允许您的代码访问响应。
但是,如果站点Access-Control-Allow-Origin
在其响应中发送 no ,则您的前端代码无法直接访问来自该站点的响应。特别是,您无法通过指定来修复它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
标头。
我可以http://catfacts-api.appspot.com/api/facts?number=99
通过邮递员到达这个端点
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS解释了为什么即使您可以使用 Postman 访问响应,浏览器也不会让您从前端访问跨域响应除非响应包含Access-Control-Allow-Origin
响应标头,否则在 Web 应用程序中运行的 JavaScript 代码。
http://catfacts-api.appspot.com/api/facts?number=99没有Access-Control-Allow-Origin
响应标头,因此您的前端代码无法访问跨域响应。
您的浏览器可以获得良好的响应,您可以在 Postman 甚至浏览器开发工具中看到它——但这并不意味着浏览器会将它暴露给您的代码。他们不会,因为它没有Access-Control-Allow-Origin
响应头。因此,您必须改为使用代理来获取它。
代理向该站点发出请求,获取响应,添加Access-Control-Allow-Origin
响应标头和所需的任何其他 CORS 标头,然后将其传递回您的请求代码。并且Access-Control-Allow-Origin
添加了标头的响应是浏览器看到的,因此浏览器让您的前端代码实际访问响应。
所以我试图将一个对象传递给我的 Fetch,这将禁用 CORS
你不想那样做。需要明确的是,当您说要“禁用 CORS”时,实际上您的意思是要禁用同源策略。CORS 本身实际上是一种方法——CORS 是一种放松同源策略的方法,而不是一种限制它的方法。
但是无论如何,您确实可以在本地环境中提供浏览器运行时标志以禁用安全性和不安全地运行,或者您可以在本地安装浏览器扩展程序来绕过同源策略,但这只是只为您在本地改变情况。
无论您在本地进行什么更改,任何其他尝试使用您的应用程序的人仍然会遇到同源策略,并且您无法为应用程序的其他用户禁用该策略。
mode: 'no-cors'
除非在少数情况下,您很可能永远不想在实践中使用,即便如此,前提是您确切地知道自己在做什么以及效果如何。这是因为设置mode: 'no-cors'
实际上对浏览器说的是,“在任何情况下都阻止我的前端 JavaScript 代码查看响应正文和标头的内容。” 在大多数情况下,这显然不是您想要的。
至于情况下,您会考虑使用mode: 'no-cors'
,请在答案限制适用于不透明的react是什么?详情。它的要点是:
在有限的情况下,当您使用 JavaScript 将来自另一个来源的内容放入<script>
, <link rel=stylesheet>
, <img>
, <video>
, <audio>
, <object>
, <embed>
, 或<iframe>
元素时(之所以有效,是因为允许跨源嵌入资源),但出于某种原因,您不这样做不想/不能仅仅通过让文档的标记使用资源 URL 作为元素的href
orsrc
属性来做到这一点。
当您想要对资源做的唯一事情就是缓存它时。正如在哪些限制适用于不透明响应中提到的那样?,在实践中的场景是当您使用 Service Workers 时,在这种情况下相关的 API 是Cache Storage API。
但即使在这些有限的情况下,也有一些重要的问题需要注意;请参阅哪些限制适用于不透明响应?详情。
我也试过传入对象 { mode: 'opaque'}
没有mode: 'opaque'
请求模式——opaque
它只是response 的一个属性,浏览器在使用no-cors
模式发送的请求的响应上设置该不透明属性。
但顺便说一句,不透明这个词是一个非常明确的信号,表明您最终得到的响应的性质:“不透明”意味着您看不到它。