2009-07-29 9 views
12

Sto trasmettendo un PDF al browser in ASP.NET 2.0. Funziona su tutti i browser su HTTP e su tutti i browser eccetto IE su HTTPS. Per quanto ne so, questo funzionava (negli ultimi 5 anni circa) in tutte le versioni di IE, ma solo di recente i nostri clienti hanno iniziato a segnalare problemi. Sospetto che il non salvi le pagine crittografate sull'opzione di sicurezza del disco utilizzata per impostazione predefinita e che a un certo punto sia stata abilitata per impostazione predefinita (Opzioni Internet -> Avanzate -> Sicurezza). Disattivare questa opzione aiuta, come soluzione, ma non è fattibile come soluzione a lungo termine.Generazione di PDF, errore con IE e HTTPS

Il messaggio di errore che sto ricevendo è:

Internet Explorer non può scaricare OutputReport.aspx da www.sitename.com.

Internet Explorer non è stato in grado di aprire questo sito Internet. Il sito richiesto non è disponibile o non può essere trovato. Per favore riprova più tardi.

Lo strumento utilizzato per creare il PDF è ActiveReports da DataDynamics. Una volta creato il PDF, ecco il codice di inviare verso il basso:

Response.ClearContent() 
Response.ClearHeaders() 
Response.AddHeader("cache-control", "max-age=1") 
Response.ContentType = "application/pdf" 
Response.AddHeader("content-disposition", "attachment; filename=statement.pdf") 
Response.AddHeader("content-length", mem_stream.Length.ToString) 
Response.BinaryWrite(mem_stream.ToArray()) 
Response.Flush() 
Response.End() 

Nota: Se non specifica esplicitamente di controllo della cache quindi .NET manda no-cache a nome mio, così ho provato a fissare controllo della cache su: privato o pubblico o maxage = #, ma nessuno di questi sembra funzionare.

Ecco la svolta: quando eseguo Fiddler per ispezionare le intestazioni di risposta, tutto funziona correttamente. Le intestazioni che ricevo sono:

HTTP/1.1 200 OK
Cache-Control: max-age = 1
Data: Mercoledì 29 Lug 2009 17:57:58 GMT
Content-Type: application/pdf
Server: Microsoft-IIS/6.0
MicrosoftOfficeWebServer: 5.0_Pub
X-Powered-By: ASP.NET
X-aspnet-Versione: 2.0.50727
Content-disposition: attachment; filename = statement.pdf
Content-Encoding: gzip
Vary: Accept-Encoding
Transfer-Encoding: chunked

Non appena mi volto Fiddler fuori e provare di nuovo, non riesce ancora una volta. Un'altra cosa che ho notato è che quando Fiddler è in esecuzione ottengo un C'è un problema con il certificato di sicurezza di questo sito Web messaggio di avviso, e devo fare clic su Continuare su questo sito (non consigliato) per passare. Quando Fiddler è disattivato, non vedo questo avviso di sicurezza e fallisce subito.

Sono curioso di ciò che sta accadendo tra Fiddler e il browser in modo che funzioni quando Fiddler è in esecuzione ma si interrompe quando non lo è, ma ancora più importante qualcuno ha idee su come posso cambiare il mio codice in modo da far scorrere i PDF in IE funziona senza apportare modifiche alla macchina client?

Aggiornamento: I problemi di Fiddler sono stati risolti, grazie mille EricLaw, quindi ora si comporta in modo coerente (interrotto, con o senza Fiddler in esecuzione).

Sulla base della ricerca di Google, sembra che ci siano molte segnalazioni di questo stesso problema su tutto il web, ciascuna con la propria combinazione specifica di intestazioni di risposta che sembrano risolvere il problema per i singoli casi. Ho provato molti di questi suggerimenti, tra cui l'aggiunta di un ETag, la data LastModified, la rimozione dell'intestazione di Vary (usando Fiddler) e dozzine di combinazioni degli header di Cache-Control e/o di Pragma. Ho provato "Content-Transfer-Encoding: binary" e "application/force-download" per ContentType. Niente ha aiutato finora. Ci sono un KBarticles , tutti che indicano che Cache-Control: no-cache è il colpevole. Altre idee?

Aggiornamento: A proposito, per completezza, questo stesso problema si verifica anche con le uscite Excel e Word.

Aggiornamento: Nessun progresso è stato effettuato. Ho mandato via email il file .SAZ da Fiddler a EricLaw e lui è riuscito a riprodurre il problema durante il debug di IE, ma non ci sono ancora soluzioni. Bounty sta per scadere ...

risposta

2

Dopo due settimane di inseguimento selvaggio, non sono stato in grado di trovare alcuna combinazione di modifiche al codice che consenta questo metodo di streaming di documenti PDF, Excel o Word quando ' Non salvare pagine crittografate su disco 'l'opzione è attiva.

Microsoft ha dichiarato che questo comportamento è di progettazione in un numero di articoli KB e di e-mail private. Sembra che quando l'opzione " Non salvare pagine crittografate su disco" sia attivata, IE si comporta correttamente e fa ciò che viene detto di fare. This post è la miglior risorsa che ho trovato finora che spiega il motivo per cui questa impostazione dovrebbe essere abilitata e i pro ei contro di consentire che:

"Il ' Non salvare pagine crittografate su disco' entra in gioco quando si ha a che fare con connessioni SSL (HTTPS). Proprio come un server web può inviare informazioni su come memorizzare un file si può fondamentalmente impostare Internet Explorer fino a non salvare i file nella cache durante una connessione SSL (HTTPS), indipendentemente se il server web ti informa che puoi.

Qual è l'aspetto positivo di questo funzione attivata, la sicurezza è il motivo principale per cui la funzionalità è attivata. Le pagine non sono memorizzate nella cache dei file temporanei Internet.

Qual è lo svantaggio? Prestazioni lente, poiché nulla viene salvato nella cache anche se l'immagine gif da 1 byte utilizzata una dozzina di volte nella pagina deve essere recuperata ogni volta dal server web. A peggiorare le cose alcune azioni utente potrebbe non riuscire, quali file scaricati saranno cancellati e un errore presentati o documenti di apertura PDF non riuscirà a citarne alcuni scenari."

La soluzione migliore che possiamo trovare in questo punto è quello di comunicare ai nostri clienti e utenti che esistono alternative all'utilizzo di questa impostazione:

"Usa 'cartella Temporary Internet Files vuota quando il browser viene chiuso'. Ogni volta che il browser si chiude, tutti i file verranno eliminati dalla cache assumendo che non ci sia un blocco su un file da un'altra istanza del browser o qualche applicazione esterna.

Prima di utilizzare ' non salvare le pagine crittografate su disco' '. Sembra una grande funzionalità di sicurezza ed è, ma i risultati dell'utilizzo di questa funzione potrebbero far sì che le chiamate all'help desk subiscano guasti di download o prestazioni lente."

0

Quale versione di IE? Ricordo che Microsoft ha rilasciato a Hotfix for IE6 per questo problema. Spero che sia di qualche utilità?

+1

IE6, IE7 e IE8 sono tutti interessati. – wweicker

3

L'intestazione Cache-Control non è corretta. Dovrebbe essere Cache-Control: max-age = 1 con il trattino nel mezzo. Prova a risolverlo per primo per vedere se fa la differenza.

In genere, direi che il colpevole più probabile è l'intestazione Vary, in quanto tali intestazioni spesso causano problemi con il caching in IE: http://blogs.msdn.com/ieinternals/archive/2009/06/17/9769915.aspx. Potresti provare ad aggiungere uno ETAG alle intestazioni di risposta.

Fiddler non dovrebbe avere alcun impatto sulla cache (a meno che tu non abbia scritto regole), e sembra che tu stia dicendo che lo fa, il che suggerisce che forse c'è un problema di temporizzazione di qualche tipo.

> Non salvare pagine crittografate opzione di protezione del disco usato di essere disabilitato per default

Questa opzione è ancora disabilitata per default (in IE6, 7 e 8), anche se gli amministratori IT possono rivolgersi tramite la politica di gruppo e alcune grandi aziende lo fanno.

Per inciso, il motivo per cui si vede l'errore del certificato durante l'esecuzione di Fiddler è che non si è scelto di fidarsi del certificato radice di Fiddler; vedi http://www.fiddler2.com/fiddler/help/httpsdecryption.asp per ulteriori informazioni su questo argomento.

+0

Grazie per la tua risposta dettagliata. Ho corretto l'intestazione del controllo cache e aggiunto un ETAG, nessuno dei quali ha risolto il problema. Dopo aver scelto di fidarsi del certificato radice di Fiddler, ora posso riprodurre il problema quando Fiddler è in esecuzione. Prima di fare ciò, il PDF funzionerebbe dopo aver fatto clic su "Continua su questo sito Web (non consigliato)" così come dici tu, forse un problema di temporizzazione di qualche tipo. – wweicker

+0

Se, all'interno di Fiddler, si utilizza la scheda Filtri per rimuovere l'intestazione di risposta "Vary", c'è qualche modifica? – EricLaw

+0

Nessuna modifica dopo aver rimosso l'intestazione di Vary ...: ~ \ – wweicker

1

Abbiamo affrontato un problema simile molto tempo fa - quello che abbiamo fatto è stato noi (questo è Java EE). Nell'applicazione di configurazione web aggiungiamo

<mime-mapping> 
    <extension>PDF</extension> 
    <mime-type>application/octet-stream</mime-type> 
</mime-mapping> 

Questo renderà qualsiasi pdf proveniente dalla propria applicazione web per essere scaricata al posto del browser cercando di rendering.

MODIFICA: sembra che lo stiate trasmettendo. In questo caso userete un tipo mime come application/octet-stream nel vostro codice e non nella config. Così, qui invece di

Response.ContentType = "application/pdf" 

userete

Response.ContentType = "application/octet-stream" 
+0

Purtroppo questo non ha aiutato. : ~/ – wweicker

0

provare a disattivare la compressione gzip.

+0

La disattivazione della compressione gzip non ha aiutato. :( – wweicker

1

ho scoperto che questo sembrava funzionare per me:

Dim browser As System.Web.HttpBrowserCapabilities = Request.Browser 
If (browser.Browser = "IE") Then 
    Response.AppendHeader("cache-control", "private") ' ie only 
Else 
    Response.AppendHeader("cache-control", "no-cache") ' all others (FF/Chrome tested) 
End If 
2

Ho avuto un problema simile con i file PDF che volevo per lo streaming Anche con Response.ClearHeaders() ho visto Pragma e Cache. Controllo delle intestazioni aggiunte in fase di esecuzione La soluzione era cancellare le intestazioni in IIS (tasto destro del mouse -> Proprietà nella pagina che carica il PDF, quindi scheda "intestazioni Http")

1

RISOLTO: questo è un problema di IE, non da apli cation ... risolvere il problema con questo: http://support.microsoft.com/kb/323308 Funziona perfetto per me, dopo aver provato per un lungo periodo.

ATT: Mr.Dark

0

Aggiunta qui sperando che qualcuno potrebbe trovare questo utile invece passare attraverso i link.

Ecco il mio codice

byte[] bytes = // get byte array from DB 

    Response.Clear(); 
    Response.ClearContent(); 
    Response.ClearHeaders(); 
    Response.Buffer = true; 

    // Prevent this page from being cached. 
    // NOTE: we cannot use the CacheControl property, or set the PRAGMA header value due to a flaw re: PDF/SSL/IE 
    Response.Expires = -1; 

    Response.ContentType = "application/pdf"; 
    // Specify the number of bytes to be sent 
    Response.AppendHeader("content-length", bytes.Length.ToString()); 

    Response.BinaryWrite(bytes);  

      // Wrap Up 
    Response.Flush(); 
    Response.Close(); 
    Response.End(); 
0

come il PO stavo graffiare la mia testa per giorni cercando di ottenere questo lavoro, ma l'ho fatto, alla fine, così ho pensato di condividere la mia 'combinazione' di intestazioni:

  if (System.Web.HttpContext.Current.Request.Browser.Browser == "InternetExplorer" 
       && System.Web.HttpContext.Current.Request.Browser.Version == "8.0") 
      { 
       System.Web.HttpContext.Current.Response.Clear(); 
       System.Web.HttpContext.Current.Response.ClearContent(); 
       System.Web.HttpContext.Current.Response.ClearHeaders(); 
       System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream"; 

       System.Web.HttpContext.Current.Response.AppendHeader("Pragma", "public"); 
       System.Web.HttpContext.Current.Response.AppendHeader("Cache-Control", "private, max-age=60"); 
       System.Web.HttpContext.Current.Response.AppendHeader("Content-Transfer-Encoding", "binary"); 

       System.Web.HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + document.Filename); 
       System.Web.HttpContext.Current.Response.AddHeader("content-length", document.Data.LongLength.ToString()); 

       System.Web.HttpContext.Current.Response.BinaryWrite(document.Data); 
      } 

La speranza che salva qualcuno da qualche parte un dolore!

0

stavo correndo in un problema simile con il tentativo di trasmettere un PDF su SSL e mettere questo all'interno di un iframe o un oggetto. Stavo scoprendo che la mia pagina aspx avrebbe continuato a reindirizzare la versione non protetta dell'URL, e il browser l'avrebbe bloccata.

ho trovato passaggio da una pagina ASPX a un gestore ASHX fisso il mio problema di reindirizzamento.