2012-03-15 15 views
11

Tengo un enlace que va a un script PHP que genera un archivo CSV para descargar y guardar. Genero los encabezados Content-Disposition y Content-Type en la respuesta. Cada navegador descarga el archivo bien excepto para Chrome (v19).Chrome está malinterpretando un archivo adjunto como documento

El enlace es algo como esto:

http://hostname.com/controller/action/export

Las cabeceras regresaron de esa solicitud son:

Cache-control:no-cache, must-revalidate 
Connection:Keep-Alive 
Content-Disposition:attachment; filename=2012-03-14.csv 
Content-Encoding:gzip 
Content-Length:521 
Content-Type:application/vnd.ms-excel 
Date:Thu, 15 Mar 2012 05:17:55 GMT 
Expires:Mon, 26 Jul 1997 05:00:00 GMT 
Keep-Alive:timeout=5, max=92 
P3P:CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM" 
Pragma:no-cache 
Server:Apache/2.2.11 (Win32) mod_ssl/2.2.11 OpenSSL/0.9.8i mod_autoindex_color PHP/5.2.9 
Vary:Accept-Encoding 
X-Powered-By:PHP/5.2.9 

Los desarrolladores de herramientas de Chrome muestra que la conexión de red fue Canceled y la ventana de la consola muestra el siguiente error:

Resource interpreted as Document but transferred with MIME type application/vnd.ms-excel: 

He intentado utilizar diferentes valores para Content-Type, he desactivado los encabezados Cache-Control y Content-Type. He probado utilizando Javascript location.href=, una etiqueta <a>, <form action="POST">, he desactivado la compresión Gzip y varios otros métodos para intentar que Chrome descargue realmente el archivo.

Cualquier otro navegador descarga bien el archivo, por lo que mi pregunta es: ¿Qué hace que Chrome interprete la solicitud como un "Documento" para mostrar en lugar de un archivo adjunto? ¿Hay otro encabezado que me falta o un encabezado en la lista que lo confunde?

EDIT: Aquí está el código PHP a lo solicitado, aunque es un poco largo:

function renderHeaders($filename = null) { 
    header("Content-Type: application/vnd.ms-excel"); 
    header("Cache-Control: public, must-revalidate, max-age=0"); 
    if (is_string($filename)) { 
    $this->setFilename($filename); 
    } 
    if ($this->filename === null) { 
    $this->filename = 'Data.csv'; 
    } 
    if ($this->filename) { 
    header("Content-disposition: attachment; filename=".$this->filename); 
    } 
} 

function render($outputHeaders = true, $to_encoding = null, $from_encoding = "auto") { 
    if ($outputHeaders) { 
    $this->renderHeaders(); 
    } 
    if ($this->_tmpFile) { 
    rewind($this->buffer); 
    $output = ''; 
    while (!feof($this->buffer)) { 
     $output .= fread($this->buffer, 8192); 
    } 
    fclose($this->buffer); 
    } else { 
    rewind($this->buffer); 
    $output = stream_get_contents($this->buffer); 
    } 
    // get around excel bug (http://support.microsoft.com/kb/323626/) 
    if (substr($output,0,2) == 'ID') { 
    $pos = strpos($output, $this->delimiter); 
    if ($pos === false) { 
     $pos = strpos($output, "\n"); 
    } 
    if ($pos !== false) { 
     $output = $this->enclosure . substr($output, 0, $pos) . $this->enclosure . substr($output, $pos); 
    } 
    } 
    if ($to_encoding) { 
    $output = mb_convert_encoding($output, $to_encoding, $from_encoding); 
    } 
    $this->clear(); 
    return $this->output($output); 
} 
+0

Se puede publicar su código php que genera las cabeceras –

+0

Creo que es posible que desee presentar un insecto) –

+0

no estoy seguro de si haría cualquier diferencia, pero ¿qué pasa con el envío de 'Content-Transfer-Encoding: Binary'? –

Respuesta

0

Es debido a su tipo de contenido.

Usted debe cambiar: Content-Type: application/vnd.ms-excel

Prueba esto:

<?php 

header("Content-Disposition: attachment; filename=$file"); 
header("Content-Type: application/zip"); 
... 
+0

¿Qué tiene que ver zip con esto? –

+0

Como dije, probé varios tipos de contenido diferentes, incluyendo application/octet-stream. Incluso apagué el encabezado de tipo de contenido todos juntos. No resolvió el problema. –

1

El tipo de contenido que está mal, debe ser text/csv, no application/vnd.ms-excel.

Fuente: Wikipedia

0

probar esto, se debe forzar su descarga en todos los navegadores.

header ("Content-type: octet/stream"); 
    header ("Content-disposition: attachment; filename=\"".$file."\";"); 
    header("Content-Length: ".filesize($file)); 
    readfile($file); 
0

Los 'application/vnd.ms-excel' tipo MIME es específicamente para archivos .xls binario de Microsoft Excel. Decir a Chrome que está enviando un archivo binario y luego entregarle un archivo de texto puede causar problemas. En su lugar, use el tipo de valores separados por comas aprobados, 'application/csv'.

Reemplazar:

header("Content-Type: application/vnd.ms-excel"); 

con:

header("Content-Type: application/csv"); 
Cuestiones relacionadas