Question

J'utilise Prawn et Prawnto pour générer un PDF dans un Ruby on Rails application (version 2.2.2 Rails) qui fonctionne très bien et génère des fichiers PDF avec bonheur et les envoie à l'utilisateur de télécharger dans Firefox.

Le problème est dans IE7.

J'ai un itinéraire mis en place comme ceci:

map.invoice_pdf '/invoices.pdf', :controller => 'invoices', 
                :action => 'index', :format => 'pdf'

Ce que j'ai alors un lien comme pour ainsi appeler:

invoice_pdf_path(:year => params[:year], :month => params[:month], 
                 :unpaid_only => params[:unpaid_only])

Et ce qui suit dans mon contrôleur:

 def index
    params[:year]  = default params[:year]
    params[:month] = default params[:month]
    params[:page] ||= 1

    @invoices = Arobl.find_invoices_for_customer(current_customer.strCustomerID,
                       params)

    respond_to do |format|
      format.html{ render :action => 'index' }
      format.pdf{
        prawnto :inline => false, :filename => 
                "#{current_customer.strCustomerID}_invoice.pdf"
  end

En FF cela fonctionne comme prévu, lorsque le lien est cliqué sur l'action show est appelée avec un format .pdf, et répond avec le PDF correctement nommé. Quand il est frappé avec IE7 il est dit que le fichier ou le site n'a pas pu être trouvé, et les références « invoices.pdf » au lieu du nom de fichier customer_id_invoice.pdf attendu.

Toute idée de ce que pourrait être la cause de ce comportement?

Merci!

Était-ce utile?

La solution 4

Comme solution provisoire, j'ai utilisé l'approche documentée ici: http://chelsearobb.wordpress.com/2009/09/09/saving-a-prawn-pdf-to-file/ et juste enregistrer le fichier localement, utilisez send_data et un fichier .read, puis supprimez le fichier qui semble fonctionner correctement dans tous les navigateurs.

Je suis toujours curieux de savoir pourquoi cela ne fonctionnerait pas dans IE7 auparavant bien.

Autres conseils

Je vais avoir ce problème aussi bien. Lorsque je tente de demander au même PDF sans SSL sur Internet Explorer (7 ou 8) il fonctionne, mais si je demande avec SSL, il ne fonctionne pas ...

Nous pensons que nous avons suivi jusqu'à ce que les en-têtes IE attend lors du téléchargement d'un fichier PDF. Je n'ai pas vérifié le code source de prawnto pour voir ce headers il se couche, mais nous allons probablement utiliser un Middleware Rack pour injecter les en-têtes dont nous avons besoin:

# add headers for PDF downloads in IE
# PDFs not downloading correctly via SSL in IE
# solution: add some headers for PDF downloads
# http://marc.info/?l=php-general&m=124301243808544&w=2
class RackAddPdfHeadersForIe
  def initialize( app )
    @app = app
  end

  def call( env )
    @status, @headers, @body = @app.call env
    add_headers if is_pdf? and is_internet_explorer?        
    [@status, @headers, @body]
  end

  def is_pdf?
    @headers['Content-Type'] =~ /pdf/
  end

  def is_internet_explorer?
    @headers['User-Agent'] =~ /MSIE ([0-9]{1,}[\.0-9]{0,})/
  end

  def add_headers
    @headers['Content-Description'] = 'File Transfer'
    @headers['Content-Transfer-Encoding'] = 'binary'
    @headers['Expires'] = '0'
    @headers['Pragma'] = 'public'
  end      
end

J'ai donc essayé cela, pensé qu'il travaillerait, alors trouvé qu'en effet, il n'a toujours pas fonctionné.

Alors je fini par faire cela, pour une raison quelconque, cela a fonctionné pour moi:

class ReportsController < ApplicationController

  def payroll_summary
    respond_to do |format|
      format.pdf do 
        response.headers['Content-Disposition'] = "attachment;filename=\"#{action_name}.pdf\""
        response.headers['Content-Description'] = 'File Transfer'
        response.headers['Content-Transfer-Encoding'] = 'binary'
        response.headers['Expires'] = '0'
        response.headers['Pragma'] = 'public'
        render
      end  #format.pdf
    end #respond_to
  end #payroll_summary

end

Cette question à savoir est expliqué dans http://support.microsoft.com/kb/323308

La solution est de mettre votre en-tête Cache-Control à autre chose que sans magasin avec quelque chose comme:

response.headers["Cache-Control"] = "private, max-age=0, must-revalidate"

Plus de personnes sont susceptibles de se heurter à ce que des rails 2.3.6+ semble mettre Cache-Control pour no-magasin où les versions antérieures n'ont pas.

Je chassais mon problème vers le bas au fichier compile_support.rb de prawnto.

  # added to make ie happy with ssl pdf's (per naisayer)
  def ssl_request?
    @controller.request.env['SERVER_PROTOCOL'].downcase == "https"
  end

Nous observions que la variable d'env SERVER_PROTCOL apache a toujours été réglé sur HTTP / 1.1 même en utilisant le protocole HTTPS. Lorsque ssl_required? est faux et il est une demande de prawnto-à-dire établira Pragma = « no-cache ». C'est ce qui a été à l'origine de nos problèmes.

Si votre application utilise uniquement https, vous pouvez modifier cette fonction pour revenir toujours vrai. Si cela ne suffit pas, vous pouvez écrire une directive apache le long des lignes de:

SetEnv SERVER_PROTOCOL "https"

Je mets ce droit dans mon dossier ssl.conf et tout fonctionne maintenant comme prévu.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top