Question

J'ai créé un fichier dans le répertoire tmp avec le code du contrôleur suivant:

  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

Cela crée le fichier que je voulais dans le répertoire tmp, ce que je veux faire est de forcer l'utilisateur à télécharger ce fichier.

Sur ma machine locale, le fichier est enregistré comme chemin:

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

Et sur le serveur en direct cette URL sera Somthing totalement différent.

Ce que je me demandais comment puis-je forcer l'utilisateur à télécharger ce xxxx.html?

P.S. Si je mets un ...

redirect_to file_path

... sur le contrôleur juste donner moi une route non trouvé.

Vive.

Était-ce utile?

La solution

Jetez un oeil à la méthode send_file . Il avait l'air quelque chose comme ceci:

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

: Peines => « attachement » forcera le navigateur à télécharger le fichier au lieu de le rendre. Réglez-le sur « inline » si vous voulez charger dans le navigateur. Si nginx est en face de votre application Rails, vous devrez modifier la configuration de votre environnement (environnements / production.rb.):

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

Autres conseils

Il est facile de chemins de fichiers avec des URL confondez, mais il est une distinction importante. Ce qui a un chemin d'URL de /a/b.txt est en fait situé dans le chemin du système #{Rails.root}/public/a/b.txt de sorte que vous devrez peut-être résoudre ce problème en générant à la fois en tandem.

Voici comment vous pouvez répondre à cette question:

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

Vous ne pouvez pas rediriger vers une ressource qui est pas exposé via votre serveur web, et généralement seules choses à public/ sont mis de cette façon. Vous pouvez inclure des chemins supplémentaires si vous configurez votre serveur en conséquence.

Vous pouvez également pas de côté tout ce processus en rendant simplement la réponse en tant que pièce jointe en ligne téléchargeable, si vous préférez:

render(:action => :show, :layout => nil, :content_type=> 'application/octet-stream')
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top