Как сделать скачивание файлов в браузере вместо их открытия на сайте!

Приветствую, Вас уважаемые читатели! Продолжаю делится с вами своим опытом решения различных (порой совсем не типичных) задач веб-разработки. И сегодня хочу вам  рассказать о том как сделать прямую ссылку на скачивания файлов формата PDF. JPG, GIF, DOCX и прочих, на своем сайте. Кто не совсем понимает о чем речь немного поясню.

Дело в том что современные браузеры , при клике на ссылку, которая ведет на файл pdf (и прочие), открывают данный формат в новом окне в своем встроенном редакторе.  Это достаточно удобно, когда нам нужно  чтобы пользователь мог просмотреть pdf файл или изображение прямо в браузере. Но проблемы возникаю, когда нам нужно предложить пользователям скачать изображение, docx — файл или pdf. Вот в этом то случаи и начинаются «танцы с бубном»,  так как если мы ставим ссылку на такие форматы, браузер просто-напросто открывает их у себя в новом окне, что нас никак не устраивает. Как же решить данную проблему?  А решается данная проблема несколькими способами,  о которых, честно говоря я и сам узнал совсем недавно.

Буквально пару дней назад на одном из сайтов заказчика  мне нужно было, чтобы пользователь при клике по ссылке мог напрямую скачать pdf файл или любой другой формат не открывая его в браузере. download-pdfНужно было что бы при клике открывалось стандартное окно для сохранения файла на компьютере.

pdf-ok

Конечно вы можете сказать, что самый простой способ — запаковать файл в архив и давать ссылку на архив, тогда браузер будет полюбому предлагать сохранить файл на компьютере. Да все верно, но это если на это готов заказчик  и если это не изображение (добавлять изображение в архив, для того чтобы пользователь мог его скачать себе на компьютер, по-моему , что-то с области дебилизма 🙂 ), да и еще кучу если… Но нам поставлена конкретная задача при клике по ссылке на файл,  файл должен скачиваться и точка. Ну что же давай  наконец-то рассмотрим способы решения данной проблемы!

Способ №1. Добавление специальной дерективы в файл .htaccess!

Один из самых распространенных способов решения вышеописанной проблемы заключается в добавление в файл .htaccess (если вы не знаете, что это за файл гугл вам в помощь 🙂 ) специальной директивы, которая запрещает открытие файлов в браузере, а заставляет их загружаться на компьютер (если говорить правильней переопределяет mime тип). Данная директива выглядит следующим образом:

 AddType application/octet-stream .pdf 

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

Если же вам нужно загружать изображение при клике на ссылку прописываем .htaccess следующее:

 
AddType application/octet-stream .png
AddType application/octet-stream .gif
AddType application/octet-stream .jpg

Думаю основную суть вы уловили.

Кстати,  практически тоже самое, вы сможете сделать прописав директивы:

 
AddType application/x-force-download.png
AddType application/x-force-download.gif
AddType application/x-force-download.jpg

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

В этом случаи можно переопределить mime тип воспользовавшись следующим  кодом:

RewriteRule .*\.(pdf|png|gif|jpg)$ - [L,T=application/octet-stream]

Вышеописанная директива менее понятна, но судя по отзывам на форумах работает практически  везде (сам я её не использовал)

Способ №2. PHP скрипт!

Бывает  хостер загоняет нас в условия, когда мы особо не можем управлять настройками сервера используя  .htaccess (увы и ах, это бывает очень часто) приходится выкручиваться скриптовыми решениями, а именно:

$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); // нужен для некоторых браузеров
header("Content-Type: $ctype");
header("Content-Disposition: attachment; filename=\"".basename($filename)."\";" );
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename)); // необходимо доделать подсчет размера файла по абсолютному пути
readfile("$filename");
exit();

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

<a href="filesave.php?filename=file.pdf">Скачать</a>

Надеюсь данная строка не требует от меня пояснений.  После этого все ваши файлы будут напрямую загружаться на компьютер. Что касается скрипта, то понятное дело, желательно его использовать если вы хоть немного понимаете, что там написано, иначе без кучи косяков и вопросов «Ну почему оно не работает!» не обойтись. Поэтому сами решайте использовать данный способ или тот, который описан ниже.

Способ №3. Используем новый атрибут download!!!

Это, как по мне, самый лучший способ заставить браузер загружать файл по прямой ссылке!  Это новый атрибут ссылки, который появится только в HTML 5 . Несмотря на это данный атрибут, в принципе, нормально поддерживается всеми современными браузерами. Как использовать download? Все достаточно просто, вот вам наглядный пример:

<a href="/filename.pdf" download>Скачать файл</a>

Данный атрибут не имеет никаких параметров просто прописываете его в ссылке и всё. После этого браузер не будет переходить по ссылке, а предложит скачать файл указанный в адресе ссылки файл.

Вот, в принципе, все способы с помощью которых вы можете заставить браузер скачивать любой  файл (будь-то pdf, doc, docx, png, jpg, mp3 и другие) не открывая его.  На этом у меня всё, до новых встреч!!!