Я даю ссылку на файл pdf на своей веб-странице для загрузки, как показано ниже
<a href = "myfile.pdf">Download Brochure</a>
Проблема в том, что когда пользователь нажимает на эту ссылку,
Но я хочу, чтобы он всегда появлялся у пользователя для загрузки, независимо от того, установлен ли Adobe acrobat или нет.
Подскажите, пожалуйста, как я могу это сделать?






Вместо ссылки на файл .PDF сделайте что-нибудь вроде
<a href = "pdf_server.php?file=pdffilename">Download my eBook</a>
который выводит настраиваемый заголовок, открывает PDF-файл (двоичный сейф) и печатает данные в браузере пользователя, после чего они могут выбрать сохранение PDF-файла, несмотря на настройки своего браузера. Pdf_server.php должен выглядеть так:
header("Content-Type: application/octet-stream");
$file = $_GET["file"] .".pdf";
header("Content-Disposition: attachment; filename = " . urlencode($file));
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . filesize($file));
flush(); // this doesn't really matter.
$fp = fopen($file, "r");
while (!feof($fp))
{
echo fread($fp, 65536);
flush(); // this is essential for large downloads
}
fclose($fp);
PS: и, очевидно, запустите некоторые проверки работоспособности в переменной "file", чтобы люди не могли украсть ваши файлы, например, не принимать расширения файлов, запрещать косые черты, добавлять .pdf к значению
Я столкнулся с другой проблемой: мой файл находится в /products/brochure/myfile.pdf. Я даю переменную $ file как $ file_path = $ _SERVER ['DOCUMENT_ROOT']. '/ Products / brochure /'. $ файл; но он загружает файл как "% 2Fvar% 2Fwww% 2Fweb15% 2Fweb% 2Fproducts% 2Fbrochure% 2myfile.pd f"
что я могу сделать, чтобы он загружался только с именем "myfile.pdf". Я изменил заголовок («Content-Disposition: attachment; filename =». Urlencode ('myfile.pdf')); также, но все еще не работает.
Я единственный получаю сообщение об ошибке, что .pdf был поврежден, когда я пытаюсь открыть .pdf?
@TravisO "Content-type: application/force-download" здесь нигде не указан: iana.org/assignments/media-types/application Это полностью поддельный заголовок. Пожалуйста, не придумывайте заголовки и не отправляйте их. Не могли бы вы обновить свой ответ. Спасибо.
После того, как погуглил об этом и дважды проверил, он удален
@TravisO У меня ошибка, это либо неподдерживаемый тип файла, либо файл был поврежден ...
Однако будьте осторожны при дословном использовании этого кода. Это представляет серьезную уязвимость LFI, поскольку вы передаете GET-переменные непосредственно в fopen.
Этот код, вероятно, опасен и по-другому. Если вы передадите HTTP-ссылки на fopen, я думаю, он получит файл с другого сервера. Может использоваться злоумышленником для попытки сканирования вашей внутренней сети на наличие открытых файлов PDF.
Не говоря уже о том, как легко было бы обойти любые «проверки работоспособности», которые, как вы думаете, вы будете делать с параметром «файл». Атаки внедрения пути / обхода каталогов весьма вероятны.
Если бы я собирался использовать этот код, вместо проверки работоспособности у меня была бы база данных файлов из белого списка на моем сервере, которые можно было бы использовать с ним. Это то, что делают различные CMS. Что касается комментария @RоryMcCune, я думаю, это зависит от того, как настроен ваш PHP. Imo, php.ini должен быть настроен так, чтобы fopen не открывал вещи с удаленных серверов.
Вы также можете добавить в свой код что-то, что будет проверять дополнительный параметр $ _GET, который будет действовать как «секретный ключ» - таким образом люди не смогут создавать произвольные URL-адреса, поскольку они не будут знать ключ, который вы использовали для разрешения файл для обслуживания. Это было бы не совсем безопасно, но было бы лучше.
Я думаю, что этот ответ неверен сегодня, когда у нас есть лучшая альтернатива атрибута HTML5 download.
Это ключ:
header("Content-Type: application/octet-stream");
Content-type application / x-pdf-document или application / pdf отправляется при отправке файла PDF. Adobe Reader обычно устанавливает обработчик для этого типа MIME, поэтому браузер передает документ в Adobe Reader при получении любого из типов PDF MIME.
В приложении Ruby on Rails (особенно с чем-то вроде гема Prawn и плагина Prawnto Rails) вы можете сделать это немного проще, чем полный скрипт (как в предыдущем примере PHP).
В вашем контроллере:
def index
respond_to do |format|
format.html # Your HTML view
format.pdf { render :layout => false }
end
end
Часть render: layout => false сообщает браузеру открыть вопрос «Вы хотите загрузить этот файл?» вместо попытки визуализировать PDF-файл. Тогда вы сможете нормально ссылаться на файл: http://mysite.com/myawesomepdf.pdf
Где написать этот код? какой контроллер, я новичок в PHP, пожалуйста, объясните.
@Prashant Это не PHP, это Ruby on Rails.
@Prashant: Если вам нужен пример PHP, просмотрите те, которые находятся дальше по ветке, но, пожалуйста, прочтите комментарии о том, как они могут быть небезопасными.
Не зацикливаться через каждую строку файла. Вместо этого используйте файл для чтения, это быстрее. Это не на сайте php: http://php.net/manual/en/function.readfile.php
$file = $_GET["file"];
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header("Content-Type: application/force-download");
header('Content-Disposition: attachment; filename=' . urlencode(basename($file)));
// header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
exit;
}
Обязательно очистите вашу переменную get, так как кто-то может загрузить некоторые файлы php ...
Функция файл для чтения действительно быстрее. Я лично рекомендую использовать этот ответ вместо принятого
Вместо использования PHP-скрипта для чтения и очистки файла удобнее переписать заголовок с помощью .htaccess. Это сохранит "красивый" URL (myfile.pdf вместо download.php?myfile).
<FilesMatch "\.pdf$">
ForceType applicaton/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
Разве это не заставит ВСЕ ваши PDF-файлы принудительно загрузить?
@TecBrat Да, но именно об этом спросил ОП. Если вы хотите ограничиться несколькими PDF-файлами, отредактируйте регулярное выражение ^\.pdf$.
@TecBrat или поместите файл .htaccess только в подпапку, где это поведение необходимо.
Попробуй это:
<a href = "pdf_server_with_path.php?file=pdffilename&path=http://myurl.com/mypath/">Download my eBook</a>
Код внутри pdf_server_with_path.php:
header("Content-Type: application/octet-stream");
$file = $_GET["file"] .".pdf";
$path = $_GET["path"];
$fullfile = $path.$file;
header("Content-Disposition: attachment; filename = " . Urlencode($file));
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");
header("Content-Length: " . Filesize($fullfile));
flush(); // this doesn't really matter.
$fp = fopen($fullfile, "r");
while (!feof($fp))
{
echo fread($fp, 65536);
flush(); // this is essential for large downloads
}
fclose($fp);
Это обычная проблема, но мало кто знает, что есть простое решение HTML 5:
<a href = "./directory/yourfile.pdf" download = "newfilename">Download the pdf</a>
Где newfilename - это имя файла, предлагаемое пользователю для сохранения файла. Или по умолчанию будет использоваться имя файла на стороне сервера, если вы оставите его пустым, например:
<a href = "./directory/yourfile.pdf" download>Download the pdf</a>
Совместимость: я тестировал это на Firefox 21 и Iron, оба работали нормально. Он может не работать в браузерах, несовместимых с HTML5 или устаревших. Единственный протестированный мной браузер, который не загружал принудительно, - это IE ...
Проверить совместимость можно здесь: http://caniuse.com/#feat=download
Это простое решение, но, к сожалению, не очень широко поддерживается, особенно. нет поддержки IE caniuse.com/#feat=download
Ага, я правильно знаю. Вот почему у меня есть примечание о совместимости. И, согласно вашему источнику, IE и Safari не поддерживают этот подход или, по крайней мере, пока не поддерживают :) В любом случае, если вы хотите, чтобы все браузеры принудительно загружали, я предлагаю вместо этого проверить некоторые другие ответы ...
работает как шарм с Chrome Версия 39.0.2171.65 (64-бит)!
Решение простое, но, к сожалению, не поддерживается в IE и Safari.
говорит, что нет разрешения на доступ
Я нашел способ сделать это с помощью простого старого HTML и JavaScript / jQuery, который постепенно ухудшается. Протестировано в IE7-10, Safari, Chrome и FF:
HTML для ссылки для скачивания:
<p>Thanks for downloading! If your download doesn't start shortly,
<a id = "downloadLink" href = "...yourpdf.pdf" target = "_blank"
type = "application/octet-stream" download = "yourpdf.pdf">click here</a>.</p>
jQuery (чистый код JavaScript был бы более подробным), который имитирует нажатие на ссылку после небольшой задержки:
var delay = 3000;
window.setTimeout(function(){$('#downloadLink')[0].click();},delay);
Чтобы сделать это более надежным, вы можете добавить обнаружение функции HTML5, а если ее там нет, используйте window.open(), чтобы открыть новое окно с файлом.
Вот другой подход. Я предпочитаю не полагаться на поддержку браузера или решать эту проблему на уровне приложения, а использовать логику веб-сервера.
Если вы используете Apache и можете поместить файл .htaccess в соответствующий каталог, вы можете использовать приведенный ниже код. Конечно, вы также можете поместить это в httpd.conf, если у вас есть к нему доступ.
<FilesMatch "\.(?i:pdf)$">
Header set Content-Disposition attachment
</FilesMatch>
Директива FilesMatch - это просто регулярное выражение, поэтому ее можно настроить так детально, как вы хотите, или вы можете добавить другие расширения.
Строка заголовка делает то же самое, что и первая строка в сценариях PHP выше. Если вам нужно также установить строки Content-Type, вы можете сделать это таким же образом, но я не счел это необходимым.
Я знаю, что очень поздно отвечу на этот вопрос, но я нашел способ сделать это в javascript.
function downloadFile(src){
var link=document.createElement('a');
document.body.appendChild(link);
link.href= src;
link.download = '';
link.click();
}
Я решил использовать весь URL-адрес PDF-файла (вместо того, чтобы просто указать имя или местоположение файла в href): a href = "домен. com / pdf / filename.pdf"
если вам нужно ограничить скорость загрузки, используйте этот код !!
<?php
$local_file = 'file.zip';
$download_file = 'name.zip';
// set the download rate limit (=> 20,5 kb/s)
$download_rate = 20.5;
if (file_exists($local_file) && is_file($local_file))
{
header('Cache-control: private');
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($local_file));
header('Content-Disposition: filename='.$download_file);
flush();
$file = fopen($local_file, "r");
while(!feof($file))
{
// send the current file part to the browser
print fread($file, round($download_rate * 1024));
// flush the content to the browser
flush();
// sleep one second
sleep(1);
}
fclose($file);}
else {
die('Error: The file '.$local_file.' does not exist!');
}
?>
Для получения дополнительной информации кликните сюда
<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<title>File Uploader</title>
<script src = "../Script/angular1.3.8.js"></script>
<script src = "../Script/angular-route.js"></script>
<script src = "../UserScript/MyApp.js"></script>
<script src = "../UserScript/FileUploder.js"></script>
<>
.percent {
position: absolute;
width: 300px;
height: 14px;
z-index: 1;
text-align: center;
font-size: 0.8em;
color: white;
}
.progress-bar {
width: 300px;
height: 14px;
border-radius: 10px;
border: 1px solid #CCC;
background-image: -webkit-gradient(linear, left top, left bottom, from(#6666cc), to(#4b4b95));
border-image: initial;
}
.uploaded {
padding: 0;
height: 14px;
border-radius: 10px;
background-image: -webkit-gradient(linear, left top, left bottom, from(#66cc00), to(#4b9500));
border-image: initial;
}
</>
</head>
<body ng-app = "MyApp" ng-controller = "FileUploder">
<div>
<table = "width:100%;border:solid;">
<tr>
<td>Select File</td>
<td>
<input type = "file" ng-model-instant id = "fileToUpload" onchange = "angular.element(this).scope().setFiles(this)" />
</td>
</tr>
<tr>
<td>File Size</td>
<td>
<div ng-repeat = "file in files.slice(0)">
<span ng-switch = "file.size > 1024*1024">
<span ng-switch-when = "true">{{file.size / 1024 / 1024 | number:2}} MB</span>
<span ng-switch-default>{{file.size / 1024 | number:2}} kB</span>
</span>
</div>
</td>
</tr>
<tr>
<td>
File Attach Status
</td>
<td>{{AttachStatus}}</td>
</tr>
<tr>
<td>
<input type = "button" value = "Upload" ng-click = "fnUpload();" />
</td>
<td>
<input type = "button" value = "DownLoad" ng-click = "fnDownLoad();" />
</td>
</tr>
</table>
</div>
</body>
</html>
Вы должны объяснить, что вы предоставили в своем коде. Даже в краткой форме, если это невозможно в деталях или не требуется в деталях.
Этого можно добиться с помощью HTML.
<a href = "myfile.pdf">Download Brochure</a>
Добавьте к нему атрибут загрузки: Здесь имя файла будет myfile.pdf
<a href = "myfile.pdf" download>Download Brochure</a>
Укажите значение атрибута загрузки:
<a href = "myfile.pdf" download = "Brochure">Download Brochure</a>
Здесь имя файла будет Brochure.pdf.
Действительно ли имеет значение, использую ли я следующий код $ file = $ _GET ["file"]. ". Pdf"; AS $ file = $ _REQUEST ["файл"]. ". Pdf";