2009-10-20 12 views
8

Gente, sé que ha habido muchos hilos sobre forzar el diálogo de descarga para aparecer, pero ninguna de las soluciones funcionó para mí todavía.PHP: descarga forzosa de archivos e IE, otra vez

Mi aplicación envía correo a la cuenta de correo electrónico del usuario, notificándoles que "otro usuario les envió un mensaje". Esos mensajes pueden tener enlaces a archivos de Excel. Cuando el usuario hace clic en un enlace en su GMail/Yahoo Mail/Outlook a ese archivo de Excel, quiero que aparezca el cuadro de diálogo Guardar archivo.

Problema: cuando hago clic con el botón derecho y hago "Guardar como" en IE, aparece el cuadro de diálogo Guardar como. Cuando hago clic en el enlace (que muchos de mis clientes harán ya que no conocen la informática), recibo un mensaje de error de IE: "IE no puede descargar el archivo ... desde ...". Puede ser relevante: en GMail, donde estoy probando esto, cada enlace es un enlace "target = _blank" (forzado por Google).

Todos los demás navegadores funcionan bien en todos los casos.

Éstos son mis jefes (capturados a través violinista):

HTTP/1.1 200 OK 
Proxy-Connection: Keep-Alive 
Connection: Keep-Alive 
Content-Length: 15872 
Via: **** // proxy server name 
Expires: 0 
Date: Tue, 20 Oct 2009 22:41:37 GMT 
Content-Type: application/vnd.ms-excel 
Server: Apache/2.2.11 (Unix) DAV/2 mod_ssl/2.2.11 OpenSSL/0.9.8i mod_python/3.3.1 Python/2.5.2 SVN/1.4.6 mod_apreq2-20051231/2.6.0 mod_perl/2.0.4 Perl/v5.10.0 
Cache-Control: private 
Pragma: no-cache 
Last-Modified: Tue, 20 Oct 2009 22:41:37 GMT 
Content-Disposition: attachment; filename="myFile.xls" 
Vary: Accept-Encoding 
Keep-Alive: timeout=5, max=100 

Quiero regular de comportamiento clic izquierdo del IE para trabajar. ¿Algunas ideas?

Respuesta

13

Esto comprobará las versiones de IE y establecerá los encabezados en consecuencia.

// assume you have a full path to file stored in $filename 
if (!is_file($filename)) { 
    die('The file appears to be invalid.'); 
} 

$filepath = str_replace('\\', '/', realpath($filename)); 
$filesize = filesize($filepath); 
$filename = substr(strrchr('/'.$filepath, '/'), 1); 
$extension = strtolower(substr(strrchr($filepath, '.'), 1)); 

// use this unless you want to find the mime type based on extension 
$mime = array('application/octet-stream'); 

header('Content-Type: '.$mime); 
header('Content-Disposition: attachment; filename="'.$filename.'"'); 
header('Content-Transfer-Encoding: binary'); 
header('Content-Length: '.sprintf('%d', $filesize)); 
header('Expires: 0'); 

// check for IE only headers 
if (preg_match('~MSIE|Internet Explorer~i', $_SERVER['HTTP_USER_AGENT']) || (strpos($_SERVER['HTTP_USER_AGENT'], 'Trident/7.0; rv:11.0') !== false)) { 
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
    header('Pragma: public'); 
} else { 
    header('Pragma: no-cache'); 
} 

$handle = fopen($filepath, 'rb'); 
fpassthru($handle); 
fclose($handle); 
+0

Muchas gracias. ¡Salvó mi vida! Y he vuelto a la cordura otra vez :) –

+1

después de la verificación y la verificación previa no hagas lo que crees que hacen. Deberías sacarlos. – EricLaw

+0

Se agregó soporte para IE 11 y se corrigió un error en el código. –

2

Si intenta hacer que el archivo se descargue cada vez, cambie el tipo de contenido a 'application/octet-stream'.

Pruébalo sin la declaración pragma.

5

sólo tiene que utilizar:

header('Content-Disposition: attachment'); 

eso es todo. (Facebook hace lo mismo.)