用于文件下载的HTTP头

我写了一个处理文件下载的PHP脚本,确定正在请求哪个文件,并设置正确的HTTP头来触发浏览器实际下载文件(而不是在浏览器中显示)。

我现在有一个问题,有些用户报告某些文件被错误地识别(所以无论扩展名,浏览器会认为它是一个GIF图像)。 我猜这是因为我没有在响应头中设置“Content-type”。 这是最有可能的情况吗? 如果是这样,是否有一个相当通用的types可以用于所有文件,而不是试图考虑每种可能的文件types?

目前我只设置值“Content-disposition:attachment; filename = arandomf.ile”

更新:我遵循这个指南在这里build立一个更强大的文件下载过程( http://w-shadow.com/blog/2007/08/12/how-to-force-file-download-with-php/ ) ,但脚本执行时和浏览器的下载对话框出现之间存在显着的延迟。 任何人都可以识别造成这一问题的瓶颈吗?

这是我的实现:

/** * 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); } } } 

根据RFC 2046(多用途Internet邮件扩展) :

build议采取的措施为执行收到一个
“application / octet-stream”实体只是提供将数据放入一个文件中

所以我会去那个。

正如Alex的链接所解释的,您可能会错过Content-Type顶部的Content-Type Content-Disposition

所以像这样的东西:

 Content-Disposition: attachment; filename=MyFileName.ext 

你可以试试这个强制下载脚本 。 即使你不使用它,也可能指向你正确的方向:

 <?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();