【问题标题】:How can I download a file from a URL and save it in Rails?如何从 URL 下载文件并将其保存在 Rails 中?
【发布时间】:2011-01-31 17:40:56
【问题描述】:

我有一个我想在本地保存的图像的 URL,以便我可以使用 Paperclip 为我的应用程序生成缩略图。下载和保存图像的最佳方式是什么? (我研究了 ruby​​ 文件处理,但没有遇到任何问题。)

【问题讨论】:

    标签: ruby-on-rails ruby file-handling


    【解决方案1】:

    以上所有示例都很棒。 就我而言,我只是想从 URL 中的图像创建一个下载链接。

    如果你想让它可下载(到你的下载文件夹),你可以在你的控制器中使用以下代码:

    require 'open-uri'
    file_type = url.to_s.split(".")[-1]
    
    send_data open(url).read, filename: "some_name.#{file_type}", type: "image/#{file_type}", disposition: "attachment"
    

    【讨论】:

      【解决方案2】:

      这可能是最简单的方法:

      IO.copy_stream(URI.open("https://i.pinimg.com/originals/24/17/d6/2417d6b3f3dc236b0b5b80fb00b3a791.png"), 'destination.png')
      

      【讨论】:

        【解决方案3】:

        我认为这是最清晰的方法:

        require 'open-uri'
        
        File.write 'image.png', open('http://example.com/image.png').read
        

        【讨论】:

        • sage 我是 Rails 新手,我可以在模型或控制器或视图中添加此代码
        • 视情况而定,但通常您会在模型或控制器方法中执行类似的操作。在 Rails 上下文中,您可能最好使用 ActiveStorage 等框架工具,而不是直接写入磁盘。
        【解决方案4】:

        更短的版本:

        require 'open-uri'
        download = open('http://example.com/image.png')
        IO.copy_stream(download, '~/image.png')
        

        要保持相同的文件名:

        IO.copy_stream(download, "~/#{download.base_uri.to_s.split('/')[-1]}")
        

        【讨论】:

        • 而且效率更高,因为输出不作为字符串存储在内存中。 +1
        • 虽然显示两个答案实际上很有用,所以像我这样的人可以看到两者,考虑差异,然后出于正确的原因有意识地选择这个答案:)
        • 我在使用 open 时收到来自 Rubocop 的安全警告。我用URI.parse(url).open 代替了它。在此处阅读有关该警察的更多信息:rubydoc.info/gems/rubocop/RuboCop/Cop/Security/Open
        【解决方案5】:

        如果您使用的是 PaperClip,现在会自动处理从 URL 下载。

        假设你有类似的东西:

        class MyModel < ActiveRecord::Base
          has_attached_file :image, ...
        end
        

        在您的模型上,只需将图像指定为 URL,如下所示(故意写成):

        @my_model = MyModel.new
        image_url = params[:image_url]
        @my_model.image = URI.parse(image_url)
        

        您可能希望将其放入模型中的方法中。这也适用于 Heroku 的临时文件系统。

        Paperclip 会从那里拿走它。

        来源:paperclip documentation

        【讨论】:

        【解决方案6】:

        试试这个:

        require 'open-uri'
        open('image.png', 'wb') do |file|
          file << open('http://example.com/image.png').read
        end
        

        【讨论】:

        • 这行得通。谢谢。我在一张图片上试过这个。图像未正确写入文件。好像它已经损坏或什么的。你也能指导我在 Rails 应用程序中做同样的事情吗?我可以在 Rails 应用程序中使用它吗?
        • 是的,您可以在 Rails 应用程序中使用它。文件未正确写入可能是因为我忘记以写入二进制模式打开目标。我现在将对其进行编辑。
        • 这会读取内存中的整个文件。最好的方法是IO.copy_stream(open('http://example.com/image.png'), 'destination.png')
        • rails 5, 2016,我不用require 'open-uri',直接用下面的代码
        • 这个答案对我不起作用。正确答案在这里:stackoverflow.com/a/29743394/1536309
        【解决方案7】:

        查看标准库中的Net::HTTP。该文档提供了几个有关如何使用 HTTP 下载文档的示例。

        【讨论】:

        • 这个答案需要更多的可见性,因为Kernel#open 不仅可以访问文件,还可以通过前缀管道符号(例如open("| ls"))进行进程调用。因此,在Kernel#open的参数中使用变量输入可能会导致严重的安全风险。
        猜你喜欢
        • 2019-11-18
        • 2013-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-11-25
        • 2018-06-08
        • 2021-10-01
        相关资源
        最近更新 更多