3

次のコントローラー コードを使用して、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 をダウンロードさせるにはどうすればよいですか?

PS私が置くと...

redirect_to file_path

...コントローラーでは、ルートが見つからないだけです。

乾杯。

4

2 に答える 2

4

send_fileメソッドを見てください。次のようになります。

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

:disposition => 'attachment' は、ブラウザにファイルをレンダリングする代わりに強制的にダウンロードさせます。ブラウザにロードする場合は、「インライン」に設定します。nginx が Rails アプリの前にある場合は、環境設定 (environments/production.rb) を変更する必要があります。

# For nginx:
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
于 2011-05-03T04:30:25.973 に答える
3

ファイルパスと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')
于 2011-05-02T20:35:38.310 に答える