Jak wymusić otwieranie plików w przeglądarce zamiast pobierania (PDF)?

210

Czy istnieje sposób na wymuszenie otwierania plików PDF w przeglądarce, gdy nie jest zaznaczona opcja „Wyświetlaj PDF w przeglądarce”?

Próbowałem użyć tagu embed i iframe, ale działa to tylko wtedy, gdy ta opcja jest zaznaczona.

Co mogę zrobić?

elloalisboa
źródło

Odpowiedzi:

419

Aby wskazać przeglądarce, że plik powinien być przeglądany w przeglądarce, odpowiedź HTTP powinna zawierać następujące nagłówki:

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

Aby pobrać plik zamiast go obejrzeć:

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

Cudzysłowy wokół nazwy pliku są wymagane, jeśli nazwa pliku zawiera znaki specjalne, takie, filename[1].pdfktóre w przeciwnym razie mogłyby zakłócić zdolność przeglądarki do obsługi odpowiedzi.

Sposób ustawienia nagłówków odpowiedzi HTTP będzie zależeć od serwera HTTP (lub, jeśli generujesz odpowiedź PDF z kodu po stronie serwera: twój język programowania po stronie serwera).

ColinM
źródło
13
Aby wymusić pobieranie, wolę raczej Content-Type: application / octet-stream.
Papick G. Taboada
25
@ PapickG.Taboada, ale system użytkownika może nie znać typu pliku. Np. Niektórzy użytkownicy mogli wybrać opcję „Zawsze otwieraj pliki tego typu” dla plików PDF. Być może, jeśli chcesz przesłonić preferencje użytkownika, dobrym pomysłem byłoby przesłanie strumienia oktetów, ale podanie poprawnego typu i sugerowanej nazwy pliku jest „poprawnym” sposobem na pobranie pliku.
ColinM,
2
cześć @ColinM Jestem tu trochę zdezorientowany ... mamy problemy z renderowaniem pdf, to po prostu daje zakodowany tekst. gdzie ustawiamy Content-Type: application / pdf Content-Disposition: inline; „nazwa pliku.pdf”? Bo przesyłamy go za pomocą kodu angular-js. Więc moje pytanie brzmi: czy typ zawartości należy ustawić przed przesłaniem? Ponadto otrzymujemy tylko link od zespołu zaplecza, adres URL, który podaje ścieżkę do pliku, który otwieramy w nowej karcie za pomocą: window.open (url, '_blank'). Focus ();
Kailas,
3
@Kailas Nie rozumiem, co próbujesz zrobić. Odpowiedź dotyczy nagłówków, które serwer powinien wysłać do klienta w odpowiedzi na żądanie HTTP dotyczące pliku PDF. Te nagłówki nie mają wpływu na przesyłanie pliku, musisz ustawić kod za adresem URL, ustawiając nagłówki za każdym razem, gdy zostanie pobrany przez klienta.
ColinM,
1
@ColinM Dzięki kolego, powiedziałeś dobrze, problem, kiedy debuggowaliśmy, był ustawiony jako typ MIME podczas przesyłania plików. Powinno to zrobić zespół zaplecza. Próbowałem uzyskać kody dotyczące sposobu dodawania nagłówków w skrypcie Java, ale nie powiodło się. Dzięki, jak udało mi się wyjaśnić ci prawdziwy pomysł ... :)
Kailas,
19

Jeśli używasz HTML5 (i myślę, że obecnie wszyscy go używają), istnieje atrybut o nazwie download.

Na przykład,

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

Tutaj filenamenie jest obowiązkowe, ale jeżeli jest, to zajmie to nazwę pobranego pliku.

Akshay
źródło
2
Jeśli masz kontrolę nad kodem serwera, powinieneś użyć „załącznika”, ponieważ pozwoli to na użycie tego samego kodu generowania nazw plików. Jeśli nie masz kontroli nad serwerem, jest to dobre rozwiązanie.
Christophe Roussy
Jest to genialne rozwiązanie problemu, jak zawsze, IE powstrzymuje nas od korzystania z niego: caniuse.com/#search=download
Rory
1
Należy pamiętać, że nie działa to w różnych domenach (np. Przeszkadzają zasady tego samego pochodzenia). W przypadku pobierania z jednej domeny atrybut pobierania nie będzie działać, jeśli zawartość jest przechowywana w innej domenie. CORS może zezwalać na przekazywanie tych treści (nie testowano).
vol7ron
59
Jest to dosłownie przeciwieństwo tego, o co prosi OP :)
Chuck Le Butt,
1
Tak wymyślone! : \ Źle zrozumiałem pytanie i odpowiedziałem. Ale wiele osób ląduje tutaj, znajdując tylko coś przeciwnego, dlatego nie edytowałem / nie usunąłem odpowiedzi.
Akshay,
16

Prawidłowy typ dotyczy application/pdfpliku PDF, a nie application/force-download. To wygląda jak włamanie do niektórych starszych przeglądarek. Zawsze używaj prawidłowego typu mimet, jeśli możesz.

Jeśli masz kontrolę nad kodem serwera:

  • Wymuszone pobieranie / monit: użyj header("Content-Disposition", "attachment; filename=myfilename.myextension");
  • Przeglądarka próbuje go otworzyć: użyj header("Content-Disposition", "inline; filename=myfilename.myextension");

Brak kontroli nad kodem serwera:

UWAGA: Wolę ustawić nazwę pliku po stronie serwera, ponieważ możesz mieć więcej informacji i używać wspólnego kodu.

Christophe Roussy
źródło
2

Jeśli masz Apache, dodaj to do .htaccesspliku:

<FilesMatch "\.(?i:pdf)$">
    ForceType application/octet-stream
    Header set Content-Disposition attachment
</FilesMatch>
Alex
źródło
jak możemy dodać wiele rozszerzeń? Chcę również dodać rozszerzenie DOC i XLS. Uprzejmie zasugeruj mi. Z góry dziękuję.
Kamlesh
Jest to odwrotne do tego, o co się prosi
Quentin
1

Ups, w moim poprzednim poście wystąpiły błędy pisowni.

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

Jeśli nie chcesz, aby przeglądarka pytała użytkownika, użyj „inline” dla trzeciego ciągu zamiast „załącznika”. Inline działa bardzo dobrze. Plik PDF zostanie wyświetlony natychmiast, bez pytania użytkownika o kliknięcie Otwórz. Użyłem „załącznika”, a to poprosi użytkownika o otwarcie, zapisz. Próbowałem zmienić nakrętkę ustawienia przeglądarki, co nie zapobiega wyświetlaniu monitu.

trangsinh1952
źródło
4
Jaki poprzedni post?
Peter Mortensen
0

To jest dla ASP.NET MVC

Na twojej stronie 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>

W twoim kontrolerze:

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");
    }
Leon van Wyk
źródło
-1

Podczas gdy poniższe działa dobrze na Firefox, NIE działa na przeglądarkach Chrome i mobilnych.

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

Aby naprawić błąd przeglądarki Chrome i przeglądarki mobilnej, wykonaj następujące czynności:

  • Przechowuj swoje pliki w katalogu w swoim projekcie
  • Skorzystaj z przeglądarki Google PDF Viewer

Przeglądarka Google PDF może być używana w następujący sposób:

<iframe src="http://docs.google.com/gview?url=http://example.com/path/to/my/directory/pdffile.pdf&embedded=true" frameborder="0"></iframe>
Nick Kongk.
źródło
-4

Otwórz downloads.php z pliku root.

Następnie przejdź do linii 186 i zmień ją na:

        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."\";");
        }
Christian Felix Kazuya
źródło
7
Nie wspominając, że używają PHP. Co jeśli ich backend znajduje się w Pythonie lub .NET?
Maxime Rouiller,
1
... mówić o poza polem. Nie mówi nawet, o jakich ramach mówi.
Archonic
-4

Możesz to zrobić w następujący sposób:

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

Jeśli plik PDF znajduje się w jakimś folderze i ten folder nie ma uprawnień do bezpośredniego dostępu do plików w tym folderze, musisz ominąć niektóre ograniczenia dostępu do .htaccessplików przy użyciu ustawień pliku w ten sposób:

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

Ale teraz zezwól tylko na niektóre niezbędne pliki.

Użyłem tego kodu i działał idealnie.

Mohsin
źródło
Nie wspominając, że używają Apache. Co jeśli używają IIS? Czy ekspresowe?
Maxime Rouiller,
-7

Oto kolejna metoda wymuszenia wyświetlenia pliku w przeglądarce w 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>';
użytkownik 28864
źródło
1
headernie działa po rozpoczęciu wypisywania treści żądania (i nie zwraca ciągu do konkatenacji w dokumencie HTML)
Quentin
-9

Wystarczy otworzyć Adobe Reader, menu → EdytujPreferencjeInternet , a następnie przejść do trybu przeglądarki lub uzyskać szczegółowe instrukcje w różnych przeglądarkach. Spróbuj wyświetlić PDF w przeglądarce | Acrobat, Acrobat Reader .

Lawl
źródło
3
Co się stanie, jeśli nie korzystasz z AdobeReadera lub nie korzystasz z systemu Windows? Twoja odpowiedź nie zadziała. Co więcej, wymaga poproszenia użytkownika o zmianę ustawień, czego nie można zrobić w prawdziwym świecie.
Clawfire,
-12

Jeśli link do pliku .PDF otworzy się w przeglądarce.
Jeśli pole nie jest zaznaczone, powinno zawierać link do pliku .zip, aby wymusić pobranie.

Jeśli .zip nie jest opcją, użyj nagłówków w PHP, aby wymusić pobieranie

header('Content-Type: application/force-download'); 
header('Content-Description: File Transfer'); 
Kirk Strobeck
źródło
Tak, ale potrzebuję sposobu, aby wymusić otwarcie w przeglądarce, aby nie pobierać. Nie mam pojęcia, czy to możliwe.
elloalisboa
2
Jeśli nie zmuszasz go do pobrania, to zmuszasz go do otwarcia w przeglądarce. Jeśli nie otworzy się w przeglądarce, to dlatego, że użytkownik ma określone ustawienia, których nie można zastąpić lub nie ma oprogramowania do odczytu plików PDF.
Kirk Strobeck,
1
Właściwie to zobacz moją odpowiedź.
Gabriel Ryan Nahmias,
21
To jest źle. Brak aplikacji / wymuszonego pobierania. Możesz także użyć alskjdsdjk / aljksdlasdj. Przeglądarka pobierze, ponieważ nie zna tego typu MIME. Właściwy typ MIME do pobrania to aplikacja / strumień
oktetów