link force existing php http-headers download content-type

php - force - Encabezados HTTP para descargas de archivos



php force download pdf (3)

He escrito un script PHP que maneja las descargas de archivos, determina qué archivo se solicita y establece los encabezados HTTP adecuados para que el navegador descargue el archivo (en lugar de mostrarlo en el navegador).

Ahora tengo un problema donde algunos usuarios informaron que ciertos archivos se identificaron incorrectamente (por lo que independientemente de la extensión, el navegador la considerará una imagen GIF). Supongo que esto se debe a que no configuré el "tipo de contenido" en el encabezado de respuesta. ¿Es este el caso más probable? Si es así, ¿existe un tipo bastante genérico que podría usarse para todos los archivos, en lugar de tratar de dar cuenta de todos los tipos de archivos posibles?

Actualmente solo estoy configurando el valor "Content-disposition: attachment; filename = arandomf.ile"

Actualización: seguí esta guía aquí para crear un proceso más sólido para la descarga de archivos ( http://w-shadow.com/blog/2007/08/12/how-to-force-file-download-with-php/ ) , pero hay un retraso significativo entre el momento en que se ejecuta el script y cuando aparece el cuadro de diálogo de descarga del navegador. ¿Alguien puede identificar el cuello de botella que está causando esto?

Aquí está mi implementación:

/** * Outputs the specified file to the browser. * * @param string $filePath the path to the file to output * @param string $fileName the name of the file * @param string $mimeType the type of file */ function outputFile($filePath, $fileName, $mimeType = '''') { // Setup $mimeTypes = array( ''pdf'' => ''application/pdf'', ''txt'' => ''text/plain'', ''html'' => ''text/html'', ''exe'' => ''application/octet-stream'', ''zip'' => ''application/zip'', ''doc'' => ''application/msword'', ''xls'' => ''application/vnd.ms-excel'', ''ppt'' => ''application/vnd.ms-powerpoint'', ''gif'' => ''image/gif'', ''png'' => ''image/png'', ''jpeg'' => ''image/jpg'', ''jpg'' => ''image/jpg'', ''php'' => ''text/plain'' ); $fileSize = filesize($filePath); $fileName = rawurldecode($fileName); $fileExt = ''''; // Determine MIME Type if($mimeType == '''') { $fileExt = strtolower(substr(strrchr($filePath, ''.''), 1)); if(array_key_exists($fileExt, $mimeTypes)) { $mimeType = $mimeTypes[$fileExt]; } else { $mimeType = ''application/force-download''; } } // Disable Output Buffering @ob_end_clean(); // IE Required if(ini_get(''zlib.output_compression'')) { ini_set(''zlib.output_compression'', ''Off''); } // Send Headers header(''Content-Type: '' . $mimeType); header(''Content-Disposition: attachment; filename="'' . $fileName . ''"''); header(''Content-Transfer-Encoding: binary''); header(''Accept-Ranges: bytes''); // Send Headers: Prevent Caching of File header(''Cache-Control: private''); header(''Pragma: private''); header(''Expires: Mon, 26 Jul 1997 05:00:00 GMT''); // Multipart-Download and Download Resuming Support if(isset($_SERVER[''HTTP_RANGE''])) { list($a, $range) = explode(''='', $_SERVER[''HTTP_RANGE''], 2); list($range) = explode('','', $range, 2); list($range, $rangeEnd) = explode(''-'', $range); $range = intval($range); if(!$rangeEnd) { $rangeEnd = $fileSize - 1; } else { $rangeEnd = intval($rangeEnd); } $newLength = $rangeEnd - $range + 1; // Send Headers header(''HTTP/1.1 206 Partial Content''); header(''Content-Length: '' . $newLength); header(''Content-Range: bytes '' . $range - $rangeEnd / $size); } else { $newLength = $size; header(''Content-Length: '' . $size); } // Output File $chunkSize = 1 * (1024*1024); $bytesSend = 0; if($file = fopen($filePath, ''r'')) { if(isset($_SERVER[''HTTP_RANGE''])) { fseek($file, $range); while(!feof($file) && !connection_aborted() && $bytesSend < $newLength) { $buffer = fread($file, $chunkSize); echo $buffer; flush(); $bytesSend += strlen($buffer); } fclose($file); } } }


Como se explica en el enlace de Alex, probablemente le falte el encabezado Content-Disposition sobre Content-Type .

Entonces algo como esto:

Content-Disposition: attachment; filename=MyFileName.ext


Puedes probar este script de descarga de fuerza . Incluso si no lo usa, probablemente lo guiará en la dirección correcta:

<?php $filename = $_GET[''file'']; // required for IE, otherwise Content-disposition is ignored if(ini_get(''zlib.output_compression'')) ini_set(''zlib.output_compression'', ''Off''); // addition by Jorg Weske $file_extension = strtolower(substr(strrchr($filename,"."),1)); if( $filename == "" ) { echo "<html><title>eLouai''s Download Script</title><body>ERROR: download file NOT SPECIFIED. USE force-download.php?file=filepath</body></html>"; exit; } elseif ( ! file_exists( $filename ) ) { echo "<html><title>eLouai''s Download Script</title><body>ERROR: File not found. USE force-download.php?file=filepath</body></html>"; exit; }; switch( $file_extension ) { case "pdf": $ctype="application/pdf"; break; case "exe": $ctype="application/octet-stream"; break; case "zip": $ctype="application/zip"; break; case "doc": $ctype="application/msword"; break; case "xls": $ctype="application/vnd.ms-excel"; break; case "ppt": $ctype="application/vnd.ms-powerpoint"; break; case "gif": $ctype="image/gif"; break; case "png": $ctype="image/png"; break; case "jpeg": case "jpg": $ctype="image/jpg"; break; default: $ctype="application/force-download"; } header("Pragma: public"); // required header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private",false); // required for certain browsers header("Content-Type: $ctype"); // change, added quotes to allow spaces in filenames, by Rajkumar Singh header("Content-Disposition: attachment; filename=/"".basename($filename)."/";" ); header("Content-Transfer-Encoding: binary"); header("Content-Length: ".filesize($filename)); readfile("$filename"); exit();