我可以通过Postman点击这个端点http://catfacts-api.appspot.com/api/facts?number=99,它返回JSON

此外,我正在使用创建-反应-应用程序,并希望避免设置任何服务器配置。

在我的客户端代码中,我试图使用fetch来做同样的事情,但我得到了错误:

被请求对象上没有'Access-Control-Allow-Origin'报头 资源。因此,来源“http://localhost:3000”是不允许的 访问。如果不透明响应满足您的需求,请设置请求的 mode为'no-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;
  });

有趣的是,我得到的错误实际上是这个函数的语法错误。我不确定我的实际获取是坏的,因为当我删除{mode: 'no-cors'}对象,并提供了一个不同的URL,它工作得很好。

我还尝试过传入object {mode: 'opaque'},但这将从上面返回原始错误。

我相信我所需要做的就是禁用CORS..我错过了什么?


当前回答

您还可以设置反向代理,使用自托管的CORS Anywhere或Just CORS添加CORS头,如果您需要托管解决方案。

https://justcors.com/<id>/<your-requested-resource>
http://cors-anywhere.com/<your-requested-resource>

其他回答

非常简单的解决方案(配置2分钟)是使用npm的local-ssl-proxy包

用法很直接: 1. 安装包: NPM install -g local-ssl-proxy 2. 在运行local-server时,使用local-ssl-proxy——source 9001——target 9000进行掩码

注:将——目标9000替换为——“您的端口编号”,将——源9001替换为——源“您的端口编号+1”

我的解决方案是在服务器端进行

我使用c# WebClient库来获取数据(在我的例子中是图像数据)并将其发送回客户端。在您选择的服务器端语言中可能有一些非常类似的东西。

//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);
    }
}

您可以根据自己的用例对其进行调整。重点是client.DownloadData()工作时没有任何CORS错误。通常CORS问题只发生在网站之间,因此从服务器发出“跨站点”请求是可以的。

然后,React获取调用就像这样简单:

//React component

fetch(`api/ItemImage/GetItemImageFromURL?url=${imageURL}`, {            
        method: 'GET',
    })
    .then(resp => resp.json() as Promise<ItemImage>)
    .then(imgResponse => {

       // Do more stuff....
    )}

所以如果你像我一样,在localhost上开发一个网站,你试图从Laravel API获取数据,并在你的Vue前端使用它,你看到了这个问题,这是我如何解决它:

In your Laravel project, run command php artisan make:middleware Cors. This will create app/Http/Middleware/Cors.php for you. Add the following code inside the handles function in Cors.php: return $next($request) ->header('Access-Control-Allow-Origin', '*') ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); In app/Http/kernel.php, add the following entry in $routeMiddleware array: ‘cors’ => \App\Http\Middleware\Cors::class (There would be other entries in the array like auth, guest etc. Also make sure you're doing this in app/Http/kernel.php because there is another kernel.php too in Laravel) Add this middleware on route registration for all the routes where you want to allow access, like this: Route::group(['middleware' => 'cors'], function () { Route::get('getData', 'v1\MyController@getData'); Route::get('getData2', 'v1\MyController@getData2'); }); In Vue front-end, make sure you call this API in mounted() function and not in data(). Also make sure you use http:// or https:// with the URL in your fetch() call.

Pete Houston的博客文章。

您还可以设置反向代理,使用自托管的CORS Anywhere或Just CORS添加CORS头,如果您需要托管解决方案。

https://justcors.com/<id>/<your-requested-resource>
http://cors-anywhere.com/<your-requested-resource>

如果你使用Express作为后端,你只需要安装cors并导入并在app.use(cors());中使用它。 如果无法解决,则尝试切换端口。 交换端口后一定会解决