Ruby on rails,强制用户下载tmp文件



我已经在tmp目录下创建了一个文件,其中包含以下控制器代码:

  def download
    file_path = "#{RAILS_ROOT}/tmp/downloads/xxx.html"
    data = render_to_string( :action => :show, :layout => nil )
    File.open(file_path, "w"){|f| f << data }
    flash[:notice] = "saved to #{file_path}"
  end

这将在tmp目录下创建我想要的文件,我想做的是强制用户下载该文件。

在我的本地机器上,文件保存到如下路径:

/Users/xxxx/Documents/Sites/xxxx/Website/htdocs/tmp/downloads/xxxx.html

而在实际服务器上,这个url将是完全不同的。

我想知道的是我如何强迫用户下载这个xxxx.html ?

注:如果我放一个…

redirect_to file_path

…在控制器上,它只是给我一个没有找到的路由。

欢呼。

看一下send_file方法。它看起来像这样:

send_file Rails.root.join('tmp', 'downloads', 'xxxxx.html'), :type => 'text/html', :disposition => 'attachment'

:disposition => 'attachment'将强制浏览器下载文件而不是呈现它。如果你想让它在浏览器中加载,就把它设为'inline'。如果nginx是在你的Rails应用程序的前面,那么你将不得不修改你的环境配置(即。环境/production.rb):

# For nginx:
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'

很容易将文件路径与url混淆,但这是一个重要的区别。URL路径为/a/b.txt的内容实际上位于系统路径#{Rails.root}/public/a/b.txt中,因此您可能需要通过串联生成两者来解决此问题。

你可以这样写:

def download
  base_path = "downloads/xxx.html"
  system_path = File.expand_path("public/#{base_path}", Rails.root)
  url_path = "/#{base_path}"
  File.open(file_path, "w") do |f|
    f.puts render_to_string(:action => :show, :layout => nil)
  end
  flash[:notice] = "saved to #{base_path}"
  redirect_to(url_path)
end

你不能重定向到一个没有通过你的web服务器暴露的资源,通常只有在public/的事情是这样设置的。如果您对服务器进行了相应的配置,则可以包含额外的路径。

如果您愿意,还可以通过简单地将响应呈现为可下载的内联附件来绕过整个过程:

render(:action => :show, :layout => nil, :content_type=> 'application/octet-stream')

相关内容

  • 没有找到相关文章

最新更新