尝试使用fetch和pass in模式:no-cors

时间:2017-04-06 17:36:06

标签: reactjs cors fetch-api create-react-app

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

此外,我正在使用create-react-app,并希望避免设置任何服务器配置。

在我的客户端代码中,我尝试使用fetch执行相同的操作,但我收到错误:

  

否'访问控制 - 允许 - 来源'标题出现在请求的上   资源。起源' http://localhost:3000'因此是不允许的   访问。如果不透明的响应满足您的需求,请设置请求   模式为' 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;
  });

有趣的是,我得到的错误实际上是这个函数的语法错误。我不确定我的实际fetch是否已被破坏,因为当我删除{mode:' no-cors' } object,并为它提供一个不同的URL,它可以正常工作。

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

我相信我需要做的就是禁用CORS ..我缺少什么?

6 个答案:

答案 0 :(得分:2)

如果您将Express用作后端,则只需安装cors并将其导入并在app.use(cors());中使用。 如果仍无法解决,请尝试切换端口。 切换端口后肯定会解决

答案 1 :(得分:1)

  

简单的解决方案:将以下内容添加到您要从中请求数据的php文件的顶部。

header("Access-Control-Allow-Origin: *");

答案 2 :(得分:0)

对我来说,解决方案就是在服务器端完成

我使用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 fetch调用很简单:

//React component

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

       // Do more stuff....
    )}

答案 3 :(得分:0)

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

用法很简单:
1。安装软件包: npm install -g local-ssl-proxy
2.运行local-server时,请用local-ssl-proxy --source 9001 --target 9000

对其进行遮罩

PS:--target 9000替换为-- "number of your port",将--source 9001替换为--source "number of your port +1"

答案 4 :(得分:0)

因此,如果您像我一样,并且在localhost上开发一个网站,尝试从Laravel API中获取数据并在您的Vue前端中使用它,您会看到此问题,这是我如何解决的问题:

  1. 在您的Laravel项目中,运行命令php artisan make:middleware Cors。这将为您创建app/Http/Middleware/Cors.php
  2. handles的{​​{1}}函数内添加以下代码:

    Cors.php
  3. return $next($request) ->header('Access-Control-Allow-Origin', '*') ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); 的{​​{1}}数组中添加以下条目:

    app/Http/kernel.php

    (数组中还会有其他条目,例如$routeMiddleware‘cors’ => \App\Http\Middleware\Cors::class 等。还请确保您正在auth中执行此操作,因为也有另一个guest在Laravel中)

  4. 将此中间件添加到您要允许访问的所有路由的路由注册中,如下所示:

    app/Http/kernel.php
  5. 在Vue前端中,请确保您在kernel.php函数而不是Route::group(['middleware' => 'cors'], function () { Route::get('getData', 'v1\MyController@getData'); Route::get('getData2', 'v1\MyController@getData2'); }); 中调用此API。另外,请确保将mounted()data()http://通话中的URL一起使用。

归功于Pete Houston的blog article

答案 5 :(得分:0)

如果上述所有解决方案都不起作用,可能是因为文件权限的原因,有时即使您使用 Heroku 或其他方式修复了 non-cors 问题,它也会抛出 403 禁止错误。像这样设置目录/文件权限:

权限和所有权错误 网络内容文件和文件夹的所有权或权限不正确也可能导致 403 Forbidden 错误。

权限 正确权限的经验法则:

文件夹:755

静态内容:644

动态内容:700