Javascript 尝试在模式中使用获取和传递:无cors
我可以点击这个端点,Javascript 尝试在模式中使用获取和传递:无cors,javascript,reactjs,cors,create-react-app,fetch-api,Javascript,Reactjs,Cors,Create React App,Fetch Api,我可以点击这个端点,http://catfacts-api.appspot.com/api/facts?number=99通过邮递员返回JSON 此外,我正在使用CreateReact应用程序,希望避免设置任何服务器配置 在我的客户机代码中,我试图使用fetch执行相同的操作,但我得到了错误: 请求的服务器上不存在“Access Control Allow Origin”标头 资源。因此,不允许使用源“” 通道如果不透明的响应满足您的需要,请设置请求的 模式设置为“无cors”,以获取禁用cor
http://catfacts-api.appspot.com/api/facts?number=99
通过邮递员返回JSON
此外,我正在使用CreateReact应用程序,希望避免设置任何服务器配置
在我的客户机代码中,我试图使用fetch
执行相同的操作,但我得到了错误:
请求的服务器上不存在“Access Control Allow Origin”标头
资源。因此,不允许使用源“”
通道如果不透明的响应满足您的需要,请设置请求的
模式设置为“无cors”,以获取禁用cors的资源
因此,我试图将一个对象传递给我的Fetch,它将禁用CORS,如下所示:
fetch('http://catfacts-api.appspot.com/api/facts?number=99', { mode: 'no-cors'})
.then(blob => blob.json())
.then(data => {
console.table(data);
return data;
})
.catch(e => {
console.log(e);
return e;
});
有趣的是,我得到的错误实际上是这个函数的语法错误。我不确定我的实际fetch
是否被破坏,因为当我删除{mode:'no cors'}对象,并为其提供一个不同的URL时,它工作得很好
我还尝试在对象{mode:'opaque'}
中传递,但这会返回上面的原始错误
我相信我所需要做的就是禁用CORS。。我错过了什么?
模式:“没有cors”
不会神奇地让事情运转起来。事实上,这让事情变得更糟,因为它的一个效果是告诉浏览器,“在任何情况下都阻止我的前端JavaScript代码查看响应体和标题的内容。”当然,你几乎永远不会想要这样
来自前端JavaScript的跨源请求的情况是,默认情况下,浏览器会阻止前端代码访问跨源的资源。如果响应中有访问控制允许源代码
,则浏览器将放松该阻塞并允许您的代码访问响应
但是,如果一个站点在其响应中不发送访问控制允许源站
,则前端代码无法直接访问该站点的响应。特别是,您不能通过指定模式:“no cors”来修复它(事实上,这将确保前端代码无法访问响应内容)
但是,有一件事是可行的:如果您通过发送请求
您还可以使用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前面加上代理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
通过邮递员
解释了为什么即使您可以使用Postman访问响应,浏览器也不允许您从web应用程序中运行的前端JavaScript代码跨源访问响应,除非响应包含access Control Allow origin
response头
没有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代码查看所有
//Server side, api controller
[Route("api/ItemImage/GetItemImageFromURL")]
public IActionResult GetItemImageFromURL([FromQuery] string url)
{
ItemImage image = new ItemImage();
using(WebClient client = new WebClient()){
image.Bytes = client.DownloadData(url);
return Ok(image);
}
}
//React component
fetch(`api/ItemImage/GetItemImageFromURL?url=${imageURL}`, {
method: 'GET',
})
.then(resp => resp.json() as Promise<ItemImage>)
.then(imgResponse => {
// Do more stuff....
)}
header("Access-Control-Allow-Origin: *");
return $next($request)
->header('Access-Control-Allow-Origin', '*')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
‘cors’ => \App\Http\Middleware\Cors::class
Route::group(['middleware' => 'cors'], function () {
Route::get('getData', 'v1\MyController@getData');
Route::get('getData2', 'v1\MyController@getData2');
});