代码之家  ›  专栏  ›  技术社区  ›  Leo

使用GCS的下载URL获取Javascript[复制]

  •  0
  • Leo  · 技术社区  · 5 年前

    http://catfacts-api.appspot.com/api/facts?number=99 通过邮递员它回来了 JSON

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

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

    请求的上不存在“Access Control Allow Origin”头 资源。起源' http://localhost:3000 因此不允许 进入。如果一个不透明的响应满足您的需要,请设置请求的 模式设置为“no cors”以获取禁用cors的资源。

    所以我试着把一个物体传给我的取物处,这会使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时,它工作得很好。

    { mode: 'opaque'} ,但这将返回上面的原始错误。

    我相信我所要做的就是让CORS瘫痪。。我错过了什么?

    0 回复  |  直到 5 年前
        1
  •  195
  •   sideshowbarker Miguel Tomás    5 年前

    添加 mode: 'no-cors' 不会神奇地让事情运转。事实上,这会让事情变得更糟,因为它的一个作用就是告诉浏览器, 在任何情况下,阻止我的前端JavaScript代码查看响应正文和标题的内容。 当然,这几乎不是你想要的。

    Access-Control-Allow-Origin 在它的响应中,浏览器将放松阻塞,并允许代码访问响应。

    但是如果一个网站不发送 访问控制允许源 模式:“没有球衣” (事实上 确保 您的前端代码无法访问响应内容)。

    如果你通过 a CORS proxy

    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,您会发现它已经关闭 ,您也可以轻松地将自己的代理部署到Heroku,只需2-3分钟,使用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/ 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/en-US/docs/Web/HTTP/Access_control_CORS 解释为什么即使您可以通过Postman访问响应,浏览器也不允许您从运行在web应用程序中的前端JavaScript代码跨源访问响应,除非响应包含 访问控制允许源

    http://catfacts-api.appspot.com/api/facts?number=99 没有 访问控制允许源 响应头,因此前端代码无法访问响应交叉源。

    您的浏览器可以很好地得到响应,您可以在Postman甚至浏览器devtoolsb中看到它,但这并不意味着浏览器将向您的代码公开它。他们不会,因为它没有 访问控制允许源

    代理向该站点发出请求,获取响应,添加 访问控制允许源 访问控制允许源 添加的头是浏览器看到的,因此浏览器允许前端代码实际访问响应。


    所以我试着把一个物体传进去,把它拿出来

    你不想那样做。很明显,当你说你想禁用CORS的时候,你实际上是说你想禁用 the same-origin policy

    但不管怎样,您确实可以在本地环境中执行一些操作,例如给浏览器运行时标志以禁用安全性并不安全地运行,或者您可以在本地安装浏览器扩展以绕过相同的源策略,但所做的只是在本地更改情况。

    你很可能不想用 模式:“没有球衣” 在实践中,除了一些有限的情况 模式:“没有球衣” 实际上对浏览器说的是, 在大多数情况下,这显然不是你想要的。


    就你的情况而言 想考虑使用 ,请参见 What limitations apply to opaque responses? 详细情况。其要点是,案例包括:

    • <script> , <link rel=stylesheet> , <img> , <video> , <audio> <object> , <embed> <iframe> 元素(这是因为这些元素允许跨源嵌入资源),但由于某些原因,您不希望或不能仅通过让文档的标记使用资源URL作为 href src 元素的属性。

    • 对不透明的回答有什么限制? Cache Storage API .

    但即使在这些有限的情况下,也有一些重要的问题需要注意; 对不透明的回答有什么限制? 详细情况。


    我也试过把这个东西传进去 { mode: 'opaque'}

    没有 mode: 'opaque' 请求模式 opaque 只是 响应 no-cors 模式。

    但顺便说一句 是一个非常明确的信号,关于你最终得到的反应的性质:不透明意味着你看不见它。

        2
  •  4
  •   dotNET    5 年前

    1. 在Laravel项目中,运行命令 php artisan make:middleware Cors app/Http/Middleware/Cors.php 为你。
    2. handles 功能 Cors.php

      return $next($request)
          ->header('Access-Control-Allow-Origin', '*')
          ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
      
    3. app/Http/kernel.php $routeMiddleware 数组:

      ‘cors’ => \App\Http\Middleware\Cors::class
      

      (数组中还有其他条目,如 auth guest 等等,也要确保你在 app/Http/kernel.php 因为还有一个 kernel.php 在拉勒维尔也一样)

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

      Route::group(['middleware' => 'cors'], function () {
          Route::get('getData', 'v1\MyController@getData');
          Route::get('getData2', 'v1\MyController@getData2');
      });
      
    5. 在Vue前端,确保在 mounted() 功能不在 data() http:// https:// fetch() 打电话来。

    blog article .

        3
  •  2
  •   Really Nice Code Erwin    5 年前

    在请求数据的php文件的顶部添加以下内容。

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

        4
  •  1
  •   Stuart Aitken    6 年前

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

    我用了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问题只在网站之间出现,因此可以从服务器发出“跨网站”请求。

    然后,React fetch调用简单如下:

    //React component
    
    fetch(`api/ItemImage/GetItemImageFromURL?url=${imageURL}`, {            
            method: 'GET',
        })
        .then(resp => resp.json() as Promise<ItemImage>)
        .then(imgResponse => {
    
           // Do more stuff....
        )}
    
        5
  •  1
  •   volna    5 年前

    local-ssl-proxy 包装自 npm

    用法很简单:
    一。安装程序包: npm install -g local-ssl-proxy
    local-server local-ssl-proxy --source 9001 --target 9000

    附笔: 替换 --target 9000 -- "number of your port" --source 9001 --source "number of your port +1"