На сервере есть папки с файлами. Настроил загрузку фалов, настроил скачивание файлов, и даже переименование. Как теперь сделать чтобы файл открылся для просмотра в новой вкладке браузера? На сервере маршрутизация моя. Прямой ссылки на файл нет, передаю имя файла параметром post запроса. Скачиваю вот так https://daruse.ru/loadfile-php Код (Text): <?php $filename = $_GET['filename']; // иначе Internet Explorer будет игнорировать Content-Disposition if(ini_get('zlib.output_compression')) ini_set('zlib.output_compression', 'Off'); $file_extension = strtolower(substr(strrchr($filename,"."),1)); if( $filename == "" ) { echo "ОШИБКА: УКАЖИТЕ ИМЯ ФАЙЛА."; exit; } elseif ( ! file_exists( $filename ) ) // проверяем файл на существование { echo "ОШИБКА: данного файла не существует."; 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 "mp3": $ctype="audio/mp3"; 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"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private",false); // нужен для Explorer header("Content-Type: $ctype"); header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" ); header("Content-Transfer-Encoding: binary"); // нужно сделать подсчет размера файла его пути header("Content-Length: ".filesize($filename)); readfile("$filename"); exit(); ?> Могу получить файл через ajax. Но как его потом открыть в новой вкладке?
Авторизация какая, на сессиях? Если на сессиях, просто давайте ссылку и не морочьте себе голову. Если на токенах, и кука не ставится - тогда чуть попотеть надо. Можно через https://developer.mozilla.org/ru/docs/Web/API/URL/createObjectURL
Авторизация на сессиях. Скрипт парсит запрос и собирает страничку. Как мне пропустить прямую ссылку на файл?
Не на файл прямую ссылку, а на ваш скрипт. Он же гетом принимает то, что надо. Значит может быть в урле. А куку браузер всё равно отправит при запросе, так что никуда сессия не денется.
У меня получается открыть новую вкладку, запросить файл, на сервере прочитать файл с диска и послать в браузер. На браузере я его получаю и обрабатываю так: Код (Javascript): function onFilesLoaded(blob) { obj_url = URL.createObjectURL(blob); const iframe = document.getElementById('viewer'); iframe.setAttribute('src', obj_url); URL.revokeObjectURL(obj_url); } Но вместо открытия файла во фрейме, он скачивается на диск. Как мне его убедить открыться для просмотра?
Я поковырялся еще. В предыдущем сообщении брехня. Все не так. На самом деле в строчке Код (Text): obj_url = URL.createObjectURL(blob); Выпадает ошибка. Uncaught TypeError: Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided. Дальше все не идет. Прямо перед этой строкой переменная blob имеет значение ����JFIFHH��C и так далее. Это у меня картинка jpg. Если ее записать на диск, то она прекрасно открывается.
На MDN нету "брехни". Значит у вас очень старый браузер, это новая фитча достаточно, на MDN есть описание, какие браузеры её поддерживают и с какими оговорками. --- Добавлено --- Ещё раз - если авторизация на сессиях, то всё это вообще не нужно. При запросе файла сессионная кука так же будет отправлена, и php её распознает
Брехня не на MDN, a у меня в посте. Моя задача вывести на новой вкладке содержимое файла. Я сделал просто тэги <embed> и <object>. В этом случае картинки прекрасно отображаются. Но другие файлы: pdf, txt, и т.п. не отображаются на странице, а скачиваются на диск. Я попробовал получить фал аяксом и потом его вывести через URL.createObjectURL(). В этом случае просто выдает ошибку на этой строке. Uncaught TypeError: Failed to execute 'createObjectURL' on 'URL': No function was found that matched the signature provided. Мой браузер Google Chrome Последняя версия Google Chrome уже установлена Версия 84.0.4147.135 (Официальная сборка), (64 бит) Я не настоящий сварщик. Вы мне твердите про какие-то куки. Я про куки ничего не знаю. Мне надо просто вывести файл на страничке.
Сделал на страничке просто ссылку на свой pdf. Все равно по ссылке скачивает, а не открывает в браузере.
Поставил на страничке рядом две ссылки Код (Text): <a href="<?= $src ?>">my link</a> <a href="https://www.w3docs.com/uploads/media/default/0001/01/540cb75550adf33f281f29132dddd14fded85bfc.pdf">w3docs</a> С сайта w3docs по ссылке открывается документ в браузере. С моего сайта начинается скачивание на диск. Ссылка $src формируется в таком виде https://mysite.com/files/show/file.pdf На сервере скрипт по адресу files.php функцией show() считывает соответствующий файл из специального каталога и отправляет тем способом, какой описан в первом посте. В чем может быть проблема? Может быть как-то по-другому надо файл отправлять с сервера в браузер?
Браузеры не обязаны открывать pdf. А вообще смотрите в сторону снабжения ваших «файлов» соотв. ContentType-заголовком. --- Добавлено --- Mля, «Content-Disposition: attachment;» впендюрили. Лучше, правда, обратитесь к кому-то. А то есть риск слетать на Луну, из-за того что нифига не сечете в коде.
Я его не впендюрвал, я взял целый франмент кода из интернета. Когда мне указали на эту строчку, я с ней разобрался, и теперь все в порядке. Спасибо.
Мы все учимся. Надеюсь, с вашей помощью я поумнею быстрее, чем случится что-то плохое. Спасибо за помощь. Можете указать на другие проблемные строки в этом корыте?
Начните с первой И чтобы открыть статик файл в отдельной вкладке, нужно к тегу ссылки приписать target=_blank и все. Ну, может еще доопределить неизвестные серверу типы файлов, хотя я бы этим не стал заниматься, т.к. браузер все равно скорее всего их проигнорит.
_blank я, разумеется, добавил. Цитата кода не моя, это фрагмент из интернета, который я переделываю для себя.
Я понял, что код не ваш. Но от этого он не перестает быть кривым. И главное вы так и не написали, нафига он вообще нужен.
Я внимательно слушаю все замечания по поводу кривизны этого кода и исправляю. Спасибо за помощь. Скажите, что еще здесь плохо. Я уже два раза написал, зачем он нужен. Напишу третий. На сервере лежат файлы, загруженные пользователем. По нажатию кнопки тот или иной файл, должен открыться в новой вкладке браузера, чтобы пользователь ознакомился с его содержимым. Цель достигнута для картинок и pdf. Как я понимаю открыть doc или xls невозможно. Использование google docs приведет к открытию содержимого для неопределенного круга лиц, что неприемлемо. Доступных библиотек для просмотра таких файлов в браузере не существует. Так что в плане функциональности я остановился, а вот замечания по безопасности и общему состоянию кода с удовольствием принимаю. Где еще код кривой?
Сервер сам умеет отдавать статик файлы. Главное ему в этом не мешать. Дырявый – это значит небезопасный. Небезопасность заключается в том, что любой пользователь может прочитать файлы, которые явно для этого не предназначены.
Чтобы отдать файлы, мы должны иметь ссылку на файл. Пользователь не имеет прямую ссылку. Его запрос содержит имя файла, а мой скрипт на сервере получает запрос и отдает файл. Только сервер знает, в какой папке лежит файл, пользователь не знает. Что нужно сделать, чтобы не мешать серверу отдать такой файл? Каждый запрос проверяется скриптом на текущего пользователя сессии. Если у пользователя нет права на файл, он его не получит. Как может любой пользователь прочитать чужой файл в моем случае? Спасибо.
Редирект. Про сессии в теме не было речи. И я не об этом. Если вы будете использовать этот код, авторизованный пользователь сможет прочитать программные файлы, файлы др. пользователей и т.п. И в любом случае в реале никто тело (более-менее крупного) файла пыхом не отдает. Для этого есть псевдозаголовки, обрабатываемые самим сервером (его модулями).
Редирект - это так? Код (Text): header('Location: http://mysite/folder/file.pdf'); Когда я использую эту функцию, запрос перехватывает мой маршрутизатор, т.е. возвращаюсь в PHP. Или я неправильно понимаю ваше предложение? Можете ткнуть меня носом в пример, как в реале отдают файлы не пыхом? Спасибо.
Перед запуском фронта обычно ставится условие «если не файл» и т.п. Есть псевдозаголовки вроде X-Sendfile. --- Добавлено --- Для «Спасибо» есть спец. кнопка.