Frage

Ich habe im tmp-Verzeichnis eine Datei mit dem folgenden Controller-Code erstellt:

  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

Dadurch wird die gewünschte Datei im tmp-Verzeichnis erstellt. Ich möchte den Benutzer zwingen, diese Datei herunterzuladen.

Auf meinem lokalen Computer wird die Datei unter folgendem Pfad gespeichert:

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

Und auf dem Live-Server wird diese URL etwas völlig anderes sein.

Ich habe mich gefragt, wie ich den Benutzer dazu zwingen kann, diese xxxx.html herunterzuladen.

P.S.Wenn ich ein...

redirect_to file_path

...auf dem Controller wird mir nur angezeigt, dass die Route nicht gefunden wurde.

Prost.

War es hilfreich?

Lösung

Werfen Sie einen Blick auf die Datei senden Methode.Es würde ungefähr so ​​aussehen:

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

:disposition => 'attachment' zwingt den Browser, die Datei herunterzuladen, anstatt sie zu rendern.Stellen Sie es auf „inline“, wenn Sie möchten, dass es im Browser geladen wird.Wenn sich Nginx vor Ihrer Rails-App befindet, müssen Sie Ihre Umgebungskonfiguration ändern (d. h.Umgebungen/Produktion.rb):

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

Andere Tipps

Es ist einfach, Dateipfade mit URLs zu verwechseln, aber es ist eine wichtige Unterscheidung. Was hat einen URL -Weg von /a/b.txt befindet sich tatsächlich im Systempfad #{Rails.root}/public/a/b.txt Möglicherweise müssen Sie dies möglicherweise angehen, indem Sie beide zusammengenehmigt werden.

So können Sie das ansprechen:

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

Sie können nicht zu einer Ressource umgeleitet, die nicht über Ihren Webserver ausgesetzt ist, und im Allgemeinen nur Dinge in public/ sind auf diese Weise eingestellt. Sie können zusätzliche Pfade einfügen, wenn Sie Ihren Server entsprechend konfigurieren.

Sie können diesen gesamten Prozess auch auf der Seite streichen, indem Sie die Antwort einfach als herunterladbarer Inline-Anhang rendern, falls Sie es vorziehen:

render(:action => :show, :layout => nil, :content_type=> 'application/octet-stream')
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top