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

发布于 2024-11-04 19:32:47 字数 654 浏览 1 评论 0原文

我使用以下控制器代码在 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

在实时服务器上,此网址将完全不同。

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

聚苯乙烯 放置一个...

redirect_to file_path

如果我在控制器上

...它只会给我一条未找到的路线。干杯。

I've created a file in the tmp directory with the following controller code:

  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

This creates the file I wanted in the tmp directory, what I want to do is force the user to download that file.

On my local machine, the file is saved to path like:

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

And on the live server this url will be somthing totally different.

What I was wondering is how do I force the user to download this xxxx.html ?

P.S.
If I put a...

redirect_to file_path

...on the controller it just give's me a route not found.

Cheers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

各空 2024-11-11 19:32:47

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

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

:disposition => “附件”将强制浏览器下载文件而不是呈现它。如果您希望它在浏览器中加载,请将其设置为“内联”。如果 nginx 位于您的 Rails 应用程序之前,那么您将必须修改您的环境配置(即environments/Production.rb):

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

Take a look at the send_file method. It'd look something like this:

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

:disposition => 'attachment' will force the browser to download the file instead of rendering it. Set it to 'inline' if you want it to load in the browser. If nginx is in front of your Rails app then you will have to modify your environment config (ie. environments/production.rb):

# For nginx:
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
从﹋此江山别 2024-11-11 19:32:47

文件路径和 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')

It's easy to confuse file paths with URLs, but it is an important distinction. What has a URL path of /a/b.txt is actually located in the system path #{Rails.root}/public/a/b.txt so you may need to address this by generating both in tandem.

Here's how you might address that:

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

You cannot redirect to a resource that is not exposed through your web server, and generally only things in public/ are set this way. You can include additional paths if you configure your server accordingly.

You can also side-step this whole process by simply rendering the response as a downloadable inline attachment, if you prefer:

render(:action => :show, :layout => nil, :content_type=> 'application/octet-stream')
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文