如何从Rails应用程序下载文件

20

我似乎找不到一个简单明了的答案来解决这个问题!所有的东西都看起来过时或是不完整!

我只想让用户能够点击链接或按钮,下载一个文件(该文件位于公共文件夹中)

我尝试了这个:

#view
<%= link_to "Raw blast output" ,:action => :download, :file_name => "public/data/02_blastout/#{@bl_file}" %>
#controller
def download
    send_file "#{RAILS_ROOT}/#{params[:file_name]}"
end

但是我得到了这个错误:

No route matches {:action=>"download", :file_name=>"public/data/02_blastout/input0.fa_x_Glyma1aaunq.bl", :controller=>"cvits"}
谢谢你的帮助!!

1
这似乎是一种非常不安全的处理方式,特别是考虑到您可以直接链接到文件。 - Mario
2
有人可以像这样编辑您的链接:?file_name=config/database.yml - Mario
我非常乐意听取用户获取文件的“正确方式”!!!欢迎任何建议! - bdeonovic
1
send_file 永远不应该使用由参数设置的路径,这会打开一个主要的安全漏洞,恶意用户会利用它。 - Mario
谢谢,这正是我想要的!抱歉,我在Web开发和Rails方面还是新手。 :) StackOverflow比其他任何论坛都有更快的响应时间! - bdeonovic
显示剩余3条评论
1个回答

40

不要使用由用户设置的参数来使用send_file,这会打开一个巨大的安全漏洞,允许用户访问您的应用程序可读取的任何文件(即整个应用程序以及可能在文件系统上的其他文件)。

相反,如果文件位于公共目录下,请链接到文件本身。在您的情况下:

<%= link_to "Raw blast output", "/data/02_blastout/#{@bl_file}" %>

无需特殊的控制器动作。


2
下载不会锁定Rails进程吗?下载不应该由HTTP服务器(如Apache等)处理,而应该像这样处理:http://www.therailsway.com/2009/2/22/file-downloads-done-right/。 - Josh M.
2
如果您设置了Apache或其他服务器,它应该处理此问题。这只是链接的代码。 - Mario
1
如果这不是一个公共文件,而是只针对注册用户的呢? - miguelfg
Mario提出了一个很好的观点。但是我们可以检查文件是否在特定目录中,该目录预期为可下载内容的目录,或者文件是否在可下载文件表中注册。不是吗? - Julien Lamarche
请访问由@JoshM提到的存档链接:https://web.archive.org/web/20160201222918/http://www.therailsway.com/2009/2/22/file-downloads-done-right/ - Tun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接