Тип содержимого заголовка ответа PHP продолжает оставаться text / html - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть страница php для получения загруженных (прикрепленных) файлов.Входными данными этого файла являются имя файла и его расширение (например, jpg).Затем я преобразовываю расширение в тип содержимого, используя следующую функцию:

function ConvertToMimeType($extension) {
    $MimeTypes = array('audio/aac', 'application/x-abiword', 'application/octet-stream', 'video/x-msvideo', 'application/vnd.amazon.ebook', 'application/octet-stream', 'application/x-bzip', 'application/x-bzip2', 'application/x-csh', 'text/css', 'text/csv', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-fontobject', 'application/epub+zip', 'application/ecmascript', 'image/gif', 'text/html', 'image/x-icon', 'text/calendar', 'application/java-archive', 'image/jpeg', 'image/jpg', 'application/javascript', 'application/json', 'audio/midi', 'video/mpeg', 'application/vnd.apple.installer+xml', 'application/vnd.oasis.opendocument.presentation', 'application/vnd.oasis.opendocument.spreadsheet', 'application/vnd.oasis.opendocument.text', 'audio/ogg', 'video/ogg', 'application/ogg', 'font/otf', 'image/png', 'application/pdf', 'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-rar-compressed', 'application/rtf', 'application/x-sh', 'image/svg+xml', 'application/x-shockwave-flash', 'application/x-tar', 'image/tiff', 'application/typescript', 'font/ttf', 'application/vnd.visio', 'audio/wav', 'audio/webm', 'video/webm', 'image/webp', 'font/woff', 'font/woff2', 'application/xhtml+xml', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/xml', 'application/vnd.mozilla.xul+xml', 'application/zip', 'video/3gpp', 'audio/3gpp', 'video/3gpp2', 'audio/3gpp2', 'application/x-7z-compressed');
    $fmime = 'application/octet-stream';
    foreach ($MimeTypes as $mime) {
        if (substr($mime, strpos($mime, "/") + 1) == $extension) {
            $fmime = $mime;
            break;
        }
    }
    return $fmime;
}

Затем строки кода ниже возвращают файл клиенту:

header('Content-disposition: filename="' . $fname . '"');
header('Pragma: no-cache');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header("Content-type: " . ConvertToMimeType($AttachFileType));
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($ffullname));
echo file_get_contents($ffullname);

, но полученный файл имеет тип содержимогоtext / html и представляет собой простой текст вместо файла.Заголовок ответа выглядит следующим образом:

Status Code: 200 OK
Remote Address: 127.0.0.2:80
Referrer Policy: no-referrer-when-downgrade
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection: Keep-Alive
Content-Encoding: gzip
Content-Length: 19924
Content-Type: text/html; charset=UTF-8
Date: Mon, 24 Sep 2018 11:23:43 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive: timeout=5, max=100
Pragma: no-cache
Server: Apache/2.4.29 (Ubuntu)
Vary: Accept-Encoding

И вывод выглядит так:

sample image

Обновление

Я уже проверил, чтобы распечатать $AttachFileType и ConvertToMimeType($AttachFileType), и выводится 'jpg' и 'image / jpg', поэтому проблема не в логике.

1 Ответ

0 голосов
/ 25 сентября 2018

Кстати, вы ничего не присвоили в переменной $ AttachFileType, чем именно вы заполняете переменную $ AttachFileType?Вы передаете только расширение своей функции?Если да, то вы ошибаетесь.Если вы передаете файловый mimetype, тогда положите ваш $ AttachFileType и проверьте, что вы передаете.

Если вы передаете расширение, вы должны установить предопределенный массив расширений в качестве ключа с соответствующим типом mime в качестве значения исоответствует типу пантомимы, который вы должны вернуть.Но вы не можете доверять расширению файла, чтобы найти точный тип файла mime, и это может привести к проблеме безопасности.

Вы можете попробовать следующее решение, хотя я не проверял ваши требования, но мы используем аналогичный обходной путь в наших проектах.

function ConvertToMimeType($fileLocation) {
    $MimeTypes = array('audio/aac', 'application/x-abiword', 'application/octet-stream', 'video/x-msvideo', 'application/vnd.amazon.ebook', 'application/octet-stream', 'application/x-bzip', 'application/x-bzip2', 'application/x-csh', 'text/css', 'text/csv', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-fontobject', 'application/epub+zip', 'application/ecmascript', 'image/gif', 'text/html', 'image/x-icon', 'text/calendar', 'application/java-archive', 'image/jpeg', 'image/jpg', 'application/javascript', 'application/json', 'audio/midi', 'video/mpeg', 'application/vnd.apple.installer+xml', 'application/vnd.oasis.opendocument.presentation', 'application/vnd.oasis.opendocument.spreadsheet', 'application/vnd.oasis.opendocument.text', 'audio/ogg', 'video/ogg', 'application/ogg', 'font/otf', 'image/png', 'application/pdf', 'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-rar-compressed', 'application/rtf', 'application/x-sh', 'image/svg+xml', 'application/x-shockwave-flash', 'application/x-tar', 'image/tiff', 'application/typescript', 'font/ttf', 'application/vnd.visio', 'audio/wav', 'audio/webm', 'video/webm', 'image/webp', 'font/woff', 'font/woff2', 'application/xhtml+xml', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/xml', 'application/vnd.mozilla.xul+xml', 'application/zip', 'video/3gpp', 'audio/3gpp', 'video/3gpp2', 'audio/3gpp2', 'application/x-7z-compressed');

    $fileInfo = new finfo(FILEINFO_MIME);
    $fileMimeType = $fileInfo->file($fileLocation);

    $fileMime = 'application/octet-stream';
    if(in_array($fileMimeType, $MimeTypes))
    {
        $fileMime = $fileMimeType;
    }
    return $fileMime;
}

$fname = 'file.xxx';
$fileToDownload = 'path/to/'.$fname;

header('Content-disposition: filename="' . $fname . '"');
header('Pragma: no-cache');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header("Content-type: " . ConvertToMimeType($fileToDownload));
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($fileToDownload));

// if you want to download file use
    $fp=fopen($fileToDownload,"r");
    fpassthru($fp);
    exit();
// or 
echo file_get_contents($fileToDownload);
...