Как заставить файлы открываться в браузере вместо загрузки (PDF)?

210

Есть ли способ принудительно открыть PDF-файлы в браузере, если опция «Отображать PDF в браузере» не отмечена?

Я попытался использовать тег embed и iframe, но он работает только тогда, когда эта опция отмечена.

Что я могу сделать?

elloalisboa
источник

Ответы:

419

Чтобы указать браузеру, что файл должен просматриваться в браузере, HTTP- ответ должен включать следующие заголовки:

Content-Type: application/pdf
Content-Disposition: inline; filename="filename.pdf"

Чтобы файл был загружен, а не просмотрен:

Content-Type: application/pdf
Content-Disposition: attachment; filename="filename.pdf"

Кавычки вокруг имени файла требуются, если имя файла содержит специальные символы, например, filename[1].pdfкоторые могут нарушить способность браузера обрабатывать ответ.

То, как вы установите заголовки HTTP-ответа, будет зависеть от вашего HTTP-сервера (или, если вы генерируете PDF-ответ из серверного кода: ваш язык программирования на стороне сервера).

ColinM
источник
13
Для принудительной загрузки я использую Content-Type: application / octet-stream.
Папик Дж. Табоада
25
@ PapickG.Taboada, но тогда система пользователя может не знать тип файла. Например, некоторые пользователи, возможно, выбрали «Всегда открывать файлы этого типа» для файлов PDF. Возможно, если вы хотите переопределить пользовательские предпочтения, тогда можно использовать octet-stream, но указание правильного типа и предлагаемого имени файла - это «правильный» способ обеспечить загрузку.
ColinM
2
Привет @ColinM Я немного запутался здесь ... у нас проблемы с рендерингом PDF, он просто дает зашифрованный текст. где мы устанавливаем Content-Type: application / pdf Content-Disposition: встроенный; "filename.pdf"? потому что мы загружаем его, используя код angular-js. Итак, мой вопрос: должен ли тип контента быть установлен перед загрузкой? А также, мы получаем только ссылку от бэкэнд-команды, URL, который дает путь к файлу, который мы открываем в новой вкладке, используя: window.open (url, '_blank'). Focus ();
Кайлас
3
@Kailas Я не понимаю, что вы пытаетесь сделать .. Ответ относится к заголовкам, которые сервер должен отправить клиенту при ответе на HTTP-запрос для файла PDF. Эти заголовки не влияют на загрузку файла, вам нужно, чтобы код за URL устанавливал заголовки каждый раз, когда он загружается клиентом.
ColinM
1
@ColinM Спасибо, приятель, ты правильно сказал, что проблема, когда мы отлаживали, была связана с типом mime при загрузке файлов. Это должно сделать внутренняя команда. Я пытался получить коды о том, как добавить заголовки в сценарии Java, но не удалось. Спасибо, поскольку я получил реальную идею очищен от вас ... :)
Kailas
19

Если вы используете HTML5 (и я думаю, что в настоящее время все используют это), есть атрибут с именем download.

Например,

<a href="somepathto.pdf" download="filename">

Здесь filenameнеобязательно, но если он указан, он будет использовать это имя для загруженного файла.

Акшай
источник
2
Если у вас есть контроль над кодом сервера, вы должны использовать 'attachchement', поскольку это позволит использовать тот же код генерации имени файла. Если у вас нет контроля над сервером, это хорошее решение.
Кристоф Русси
Это блестящее решение проблемы, однако, как всегда, IE удерживает нас от его использования: caniuse.com/#search=download
Рори МакКроссан
1
Важно отметить, что это не работает между доменами (например, политика одного и того же происхождения мешает). При загрузке из одного домена атрибут загрузки не будет работать, если содержимое хранится в другом домене. CORS может пропустить этот контент (не проверял).
vol7ron
59
Это буквально противоположное тому , что просит ОП :)
Chuck Le Butt
1
Да понял! : \ Я неправильно понял вопрос и ответил. Но многие люди приземляются здесь, находя только противоположность, поэтому не отредактировали / удалили ответ.
Акшай
16

Правильный тип application/pdfдля PDF, а не application/force-download. Это выглядит как хак для некоторых старых браузеров. Всегда используйте правильный mimetype, если можете.

Если у вас есть контроль над кодом сервера:

  • Принудительная загрузка / приглашение: используйте header("Content-Disposition", "attachment; filename=myfilename.myextension");
  • Браузер пытается открыть его: использовать header("Content-Disposition", "inline; filename=myfilename.myextension");

Нет контроля над кодом сервера:

  • Используйте атрибут загрузки HTML5 . Он использует пользовательское имя файла, указанное на стороне просмотра.

ПРИМЕЧАНИЕ. Я предпочитаю указывать имя файла на стороне сервера, поскольку у вас может быть больше информации и вы можете использовать общий код.

Кристоф Русси
источник
2

Если у вас есть Apache, добавьте это в .htaccessфайл:

<FilesMatch "\.(?i:pdf)$">
    ForceType application/octet-stream
    Header set Content-Disposition attachment
</FilesMatch>
Alex
источник
Как мы можем добавить несколько расширений? Я хочу также добавить расширение DOC и XLS. Пожалуйста, предложите мне. Заранее спасибо.
Kamlesh
Это противоположно тому, о чем просят
Квентин
1

К сожалению, в моем предыдущем посте были опечатки.

    header("Content-Type: application/force-download");
    header("Content-type: application/pdf");
    header("Content-Disposition: inline; filename=\"".$name."\";");

Если вы не хотите, чтобы браузер запрашивал пользователя, используйте «inline» для третьей строки вместо «attachment». Inline работает очень хорошо. PDF-файл отображается сразу, не прося пользователя нажать кнопку «Открыть». Я использовал «вложение», и это предложит пользователю открыть, сохранить. Я попытался изменить гайку настройки браузера, это не мешает подсказке.

trangsinh1952
источник
4
Какой предыдущий пост?
Питер Мортенсен,
0

Это для ASP.NET MVC

На вашей странице cshtml:

<section>
    <h4><a href="@Url.Action("Download", "Document", new { id = @Model.GUID })"><i class="fa fa-download"></i> @Model.Name</a></h4>
    <object data="@Url.Action("View", "Document", new { id = @Model.GUID })" type="application/pdf" width="100%" height="800" class="col-md-12">
        <h2>Your browser does not support viewing PDFs, click on the link above to download the document.</h2>
    </object>
</section>

В вашем контроллере:

public ActionResult Download(Guid id)
    {
        if (id == Guid.Empty)
            return null;

        var model = GetModel(id);

        return File(model.FilePath, "application/pdf", model.FileName);
    }

public FileStreamResult View(Guid id)
    {
        if (id == Guid.Empty)
            return null;

        var model = GetModel(id);

        FileStream fs = new FileStream(model.FilePath, FileMode.Open, FileAccess.Read);

        return File(fs, "application/pdf");
    }
Леон ван Вик
источник
-1

Хотя следующее работает хорошо для Firefox, оно не работает на Chrome и мобильных браузерах.

Content-Type: application/pdf
Content-Disposition: inline; filename="filename.pdf"

Чтобы исправить ошибку браузеров chrome и mobile, сделайте следующее:

  • Храните ваши файлы в каталоге в вашем проекте
  • Используйте Google PDF Viewer

Google PDF Viewer можно использовать так:

<iframe src="http://docs.google.com/gview?url=http://example.com/path/to/my/directory/pdffile.pdf&embedded=true" frameborder="0"></iframe>
Ник Конг.
источник
-4

Откройте файл downloads.php из корневого файла.

Затем перейдите к строке 186 и измените ее следующим образом:

        if(preg_match("/\.jpg|\.gif|\.png|\.jpeg/i", $name)){
            $mime = getimagesize($download_location);
            if(!empty($mime)) {
                header("Content-Type: {$mime['mime']}");
            }
        }
        elseif(preg_match("/\.pdf/i", $name)){
            header("Content-Type: application/force-download");
            header("Content-type: application/pdf");
            header("Content-Disposition: inline; filename=\"".$name."\";");
        }

        else{
            header("Content-Type: application/force-download");
            header("Content-type: application/octet-stream");
            header("Content-Disposition: attachment; filename=\"".$name."\";");
        }
Кристиан Феликс Казуя
источник
7
Не говоря уже о том, что они используют PHP. Что делать, если их бэкэнд в Python или .NET?
Максим Роиллер
1
... говорить о вне поля. Он даже не говорит, о чем говорит.
Archonic
-4

Вы можете сделать это следующим образом:

<a href="path to PDF file">Open PDF</a>

Если файл PDF находится внутри какой-либо папки и эта папка не имеет разрешения на прямой доступ к файлам в этой папке, то вы должны обойти некоторые ограничения доступа к файлам, используя .htaccessнастройки файла следующим образом:

<FilesMatch ".*\.(jpe?g|JPE?G|gif|GIF|png|PNG|swf|SWF|pdf|PDF)$" >
    Order Allow,Deny
    Allow from all
</FilesMatch>

Но теперь разрешите только определенные необходимые файлы.

Я использовал этот код, и он работал отлично.

Mohsin
источник
Не говоря уже о том, что они используют Apache. Что если они используют IIS? Или экспресс?
Максим Роуллер
-7

Либо использовать

<embed src="file.pdf" />

если встраивание является опцией или мой новый плагин, PIFF: https://github.com/terrasoftlabs/piff

Габриэль Райан Намиас
источник
-7

Вот еще один способ заставить файл для просмотра в браузере на PHP:

$extension = pathinfo($file_name, PATHINFO_EXTENSION);
$url = 'uploads/'.$file_name;
        echo '<html>'
                .header('Content-Type: application/'.$extension).'<br>'
                .header('Content-Disposition: inline; filename="'.$file_name.'"').'<br>'
                .'<body>'
                .'<object   style="overflow: hidden; height: 100%;
             width: 100%; position: absolute;" height="100%" width="100%" data="'.$url.'" type="application/'.$extension.'">
                    <embed src="'.$url.'" type="application/'.$extension.'" />
             </object>'
            .'</body>'
            . '</html>';
user28864
источник
1
headerне работает после того, как вы начали выводить тело запроса (и не возвращает строку для конкатенации в документе HTML)
Квентин,
-9

Просто откройте Adobe Reader, меню → ПравкаНастройкиИнтернет , затем перейдите в режим браузера или для получения подробных инструкций в разных браузерах попробуйте отобразить PDF в браузере | Акробат, Акробат Ридер .

Lawl
источник
3
Что если вы не используете AdobeReader или не используете Windows? Ваш ответ не сработает. Более того, для этого нужно попросить пользователя изменить свои настройки, чего нельзя сделать в реальном мире.
Clawfire
-12

Если вы ссылаетесь на .PDF, он откроется в браузере.
Если флажок снят, он должен ссылаться на ZIP-файл, чтобы вызвать загрузку.

Если .zip не вариант, используйте заголовки в PHP для принудительной загрузки

header('Content-Type: application/force-download'); 
header('Content-Description: File Transfer'); 
Кирк Стробек
источник
Да, но мне нужен способ заставить браузер открываться, чтобы не скачивать. Я понятия не имею, если это возможно.
elloalisboa
2
Если вы не принуждаете его к загрузке, то вы принудительно открываете его в браузере. Если он не открывается в браузере, это потому, что у пользователя есть особые настройки, которые вы не можете изменить, или у них нет программного обеспечения для чтения PDF.
Кирк Стробек
1
На самом деле, смотрите мой ответ.
Габриэль Райан Намиас
21
Это не верно. Нет приложения / принудительной загрузки. Вы также можете использовать alskjdsdjk / aljksdlasdj. Браузер загрузится, потому что он не знает этот тип MIME. Правильный MIME-тип для загрузки будет мне приложение / октет-поток
Папик Г. Taboada