HTTP-Header für Dateidownloads

Ich habe ein PHP-Skript geschrieben, das Dateidownloads verarbeitet, ermittelt, welche Datei angefordert wird, und die richtigen HTTP-Header setzt, um den Browser dazu zu veranlassen, die Datei tatsächlich herunterzuladen (anstatt sie im Browser anzuzeigen).

Ich habe jetzt ein Problem, bei dem einige Benutzer gemeldet haben, dass bestimmte Dateien falsch identifiziert wurden (unabhängig von der Erweiterung wird der Browser dies als GIF-Bild betrachten). Ich vermute, das liegt daran, dass ich den “Inhaltstyp” nicht im Antwortheader eingestellt habe. Ist das höchstwahrscheinlich der Fall? Wenn ja, gibt es einen ziemlich generischen Typ, der für alle Dateien verwendet werden könnte, anstatt zu versuchen, jeden möglichen Dateityp zu berücksichtigen?

Momentan setze ich nur den Wert “Content-disposition: attachment; filename = arandomf.ile”

Update: Ich folgte dieser Anleitung hier, um einen robusteren process für das Herunterladen von Dateien zu erstellen ( http://w-shadow.com/blog/2007/08/12/how-to-force-file-download-with-php/ ) Es gibt jedoch eine erhebliche Verzögerung zwischen der Ausführung des Skripts und dem Download-Dialogfeld des Browsers. Kann jemand den Engpass identifizieren, der das verursacht?

Hier ist meine Implementierung:

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

    Laut RFC 2046 (Multipurpose Internet Mail Extensions) :

    Die empfohlene Aktion für eine Implementierung, die ein
    “application / octet-stream” -Entity soll einfach anbieten, die Daten in eine Datei zu legen

    Also würde ich für diesen gehen.

    Wie von Alex ‘Link erklärt, fehlt Ihnen wahrscheinlich die Kopfzeile Content-Disposition über Content-Type .

    So etwas wie das:

     Content-Disposition: attachment; filename=MyFileName.ext 

    Sie können dieses Force-Download-Skript ausprobieren. Selbst wenn Sie es nicht verwenden, wird es Ihnen wahrscheinlich in die richtige Richtung zeigen:

     < ?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 "eLouai's Download ScriptERROR: download file NOT SPECIFIED. USE force-download.php?file=filepath"; exit; } elseif ( ! file_exists( $filename ) ) { echo "eLouai's Download ScriptERROR: File not found. USE force-download.php?file=filepath"; 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();