mode: 'no-cors'
不会神奇地使事情起作用。实际上,这使情况变得更糟,因为它的作用之一是告诉浏览器:“在任何情况下都禁止我的前端JavaScript代码查看响应主体和标头的内容。” 当然,您几乎永远都不需要。
前端JavaScript的跨域请求会发生什么,默认情况下,浏览器会阻止前端代码访问跨域资源。如果Access-Control-Allow-Origin
响应中,则浏览器将放松该阻止,并允许您的代码访问响应。
但是,如果站点Access-Control-Allow-Origin
在响应中未发送任何信息,则您的前端代码将无法直接从该站点访问响应。特别是,您无法通过指定进行修复mode: 'no-cors'
(实际上,这将确保您的前端代码无法访问响应内容)。
但是,这将起作用:如果您通过CORS代理发送请求,如下所示:
var proxyUrl = 'https://cors-anywhere.herokuapp.com/',
targetUrl = 'http://catfacts-api.appspot.com/api/facts?number=99'
fetch(proxyUrl + targetUrl)
.then(blob => blob.json())
.then(data => {
console.table(data);
document.querySelector("pre").innerHTML = JSON.stringify(data, null, 2);
return data;
})
.catch(e => {
console.log(e);
return e;
});
<pre></pre>
注意:如果您尝试使用https://cors-anywhere.herokuapp.com时发现它已关闭,则还可以使用5条命令在2-3分钟内轻松地将自己的代理部署到Heroku中:
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前面加上https://cors-anywhere.herokuapp.com
,而是在您自己的实例的URL 前面加上前缀;例如https://cryptic-headland-94862.herokuapp.com/https://example.com。
我可以http://catfacts-api.appspot.com/api/facts?number=99
通过邮递员达到这个终点
https://developer.mozilla.org/zh-CN/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甚至浏览器devtools中看到它,但这并不意味着浏览器会将其公开给您的代码。他们不会,因为它没有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'
,请在答案限制适用于不透明的反应是什么?有关详细信息。其要点是:
在你使用JavaScript来使资源从另一个原点的内容时,有限的情况下<script>
,<link rel=stylesheet>
,<img>
,<video>
,<audio>
,<object>
,<embed>
,或<iframe>
元素(它的作品,因为资源的嵌入跨域允许那些) -但由于某种原因您不希望或者不能仅仅通过使文档的标记使用资源URL作为元素的href
or src
属性来做到这一点。
当您只想对资源进行缓存时。正如答案中提到的那样,对不透明响应有哪些限制?,实际上,适用的情况是使用Service Workers时,在这种情况下,相关的API是Cache Storage API。
但是即使在那些有限的情况下,也要注意一些重要的陷阱。请参见以下答案:不透明响应有哪些限制?有关详细信息。
我也尝试过传递对象 { mode: 'opaque'}
没有mode: 'opaque'
请求模式- opaque
而是仅是response的属性,浏览器在以该no-cors
模式发送的请求的响应上设置了该不透明属性。
但是顺便说一句,“ 不透明 ”一词是一个非常明确的信号,表示您最终得到的响应的性质:“不透明”表示您看不到它。
cors-anywhere
简单的非产品用例(例如,获取一些公开可用的数据)的解决方法。这个答案证实了我no-cors
的普遍性,因为它的OpaqueResponse不是很有用。即“非常有限的情况”;谁能向我解释一些no-cors
有用的例子?