Domanda

Ho creato un file nella directory TMP con il seguente codice controller:

  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

Questo crea il file che volevo nella directory TMP, quello che voglio fare è costringere l'utente a scaricare quel file.

Sulla mia macchina locale, il file viene salvato su un percorso come:

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

E sul server live questo URL sarà completamente diverso.

Quello che mi chiedevo è come faccio a forzare l'utente a scaricare questo xxxx.html?

Ps se metto un ...

redirect_to file_path

... Sul controller mi ha dato un percorso non trovato.

Saluti.

È stato utile?

Soluzione

Dai un'occhiata al inviare file metodo. Assomiglierebbe a questo:

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

: dispositivo => 'allegato' costringerà il browser a scaricare il file invece di renderlo. Impostalo su "Inline" se si desidera caricare nel browser. Se Nginx è di fronte all'app Rails, dovrai modificare la configurazione dell'ambiente (cioè ambienti/produzione.rb):

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

Altri suggerimenti

È facile confondere i percorsi di file con gli URL, ma è una distinzione importante. Cosa ha un percorso URL di /a/b.txt si trova effettivamente nel percorso del sistema #{Rails.root}/public/a/b.txt Quindi potrebbe essere necessario affrontarlo generando entrambi in tandem.

Ecco come potresti affrontare questo:

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

Non è possibile reindirizzare a una risorsa che non è esposta tramite il tuo server web e generalmente solo cose in public/ sono impostati in questo modo. È possibile includere percorsi aggiuntivi se si configura il tuo server di conseguenza.

È inoltre possibile attraversare l'intero processo semplicemente rendendo la risposta come allegato in linea scaricabile, se preferisci:

render(:action => :show, :layout => nil, :content_type=> 'application/octet-stream')
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top