webForumDet fria alternativet

PDF kan inte öpnnas/laddas ned av webbläsaren

PHP

5 svar · 1 226 visningar · startad av emilt

Medlem sedan aug. 20123 inlägg
Frågan#1

Hej!

Har försökt skapa ett nedladdningsskript som laddar ned en pdf-fil. Jag har tittat på lite olika exempel men av någon anledning fungerar det inte som jag vill.

Koden i min test.php ser ut som följer:

&#65279;<?php
$file = 'test2.pdf';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/pdf');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile('test2.pdf');
    exit;
}
?>

När man surfar till test.php borde man ju få möjlighet att ladda ned test2.pdf alternativt att den presenteras i webbläsaren. Men det enda som sker är att webbläsaren öppnar filen och på något sätt försöker läsa den.

Alltså, skärmen fylls med mestadels frågetecken och en del kryptiskt information som jag tycker antyder att filen "läses" av webbläsaren. Det som presenteras är bland annat:
%PDF-1.6 %���� 417 0 obj <> endobj 459 0 obj <-- Första tecknen

Sedan i slutet av hela sidan:
d endstream endobj startxref 116 %%EOF

Jag tycker det känns som om webbläsaren försöker öppna pdf-filen och sedan stega sig igenom allting. Men den borde väl använda t.ex. Adobe PDF eller ge mig möjlighet att välja "spara fil". Jag har även provat med en doc-fil med samma resultat.

Filerna i sig är det inget fel på, om man direktlänkar till dem så fungerar nedladdningen.

Medlem sedan juli 2012123 inlägg
#2

Jag är verkligen inte rätt person att hjälpa dig för jag fick nämligen hjälp på samma grej som dig för ett tag sedan :)

Så här blev min färdiga kod som jag fick hjälp med:

<?php
$fil = isset($_GET['file']) ? basename($_GET['file']) : false;
if ($fil && file_exists('./bilder/' . $fil)) {
    header("Cache-control: private");
    header("Content-Type: application/octet-stream");
    header("Content-Length: " . filesize("./bilder/".$fil));
    header("Content-Disposition: attachment; filename=" . $fil);
    $fp = fopen("./bilder/" . $fil, "rb");
    fpassthru($fp);
    fclose($fp);
    exit;
} else {
    die('File not found');
}
?>

och här är länken för att ladda ner

<a href=\"get_file.php?file={$rad['fil']}\">Ladda ner</a>

Jag hämtar iof all min information från en tabell i DB

Men, kanske kan du hitta något som du kan använda :)

Medlem sedan feb. 20034 441 inlägg
#3

emilt skrev:

Alltså, skärmen fylls med mestadels frågetecken och en del kryptiskt information som jag tycker antyder att filen "läses" av webbläsaren. Det som presenteras är bland annat:
%PDF-1.6 %���� 417 0 obj <> endobj 459 0 obj <-- Första tecknen

Är du helt säker på att det inte är några tecken före det där, det får inte ens vara ett mellanslag eller något annat före %PDF-1.6 %.

Medlem sedan aug. 20123 inlägg
#4

Japp, jag är helt säker på att jag inte har något före. Testade med maweers förslag och nu ser min kod ut såhär:

&#65279; <?php
    $basepath = 'doc/protected/';
    $file = 'test2.pdf';

    $pdf = $basepath . $file;
    
    // Skicka headers
    header("Cache-control: private");
    header("Content-Type: application/octet-stream");
    header("Content-Length: " . filesize($pdf));
    header("Content-Disposition: attachment; filename=" . $file);
    $fp = fopen($pdf, "rb");
    fpassthru($fp);
    fclose($fp);
    exit; 

    // Hämta filen
    //readfile($pdf);
?>

Det känns som om det borde vara något konstigt encoding-fel men filen som jag visat ovan är sparad i UTF-8 och det ska den väl vara? Har också testat att spara min php-fil som ANSI och UNICODE men samma resultat.

Medlem sedan aug. 20123 inlägg
#5

Har äntligen fått till detta nu. Min slutliga lösning blev att spara php-filen i formatet ANSI. Då fungerar det som det är tänkt. Visserligen fungerar inte åäö i mina felmeddelanden men det får duga som det är. Har lagt ned tillräckligt många timmar på detta nu :P.

Här är den slutliga koden:

<?php
    session_start();
    $basepath = 'doc/protected/';
    $filename = preg_replace("/[^a-zA-Z0-9._ -]/", "", str_replace(" ", "_", $_GET['file']));
    $file = $basepath . $filename;
    
    // Verify login
    if (!$_SESSION['auth'])  {
        die('Du måste logga in för att ladda ned denna fil.');
    }
    
    // Control that the file exists
    if (!file_exists($file))    {
        die('Denna fil finns inte att ladda ned');
    }
    
    // Decide what MIME-type is active
    $known_mime_types=array(
        "pdf" => "application/pdf",
        "txt" => "text/plain",
        "html" => "text/html",
        "htm" => "text/html",
        "exe" => "application/octet-stream",
        "zip" => "application/zip",
        "doc" => "application/msword",
        "xls" => "application/vnd.ms-excel",
        "ppt" => "application/vnd.ms-powerpoint",
        "gif" => "image/gif",
        "png" => "image/png",
        "jpeg"=> "image/jpg", 
        "jpg" =>  "image/jpg", 
        "php" => "text/plain" 
        );
    
    $file_extension = strtolower(substr(strrchr($file,"."),1));
    if(array_key_exists($file_extension, $known_mime_types))    {       
        $mime_type=$known_mime_types[$file_extension];
        } 
    else    {        
        $mime_type="application/force-download";
        }
    // For Internet Explorer
    if (ini_get('zlib.output_compression'))  {  
        ini_set('zlib.output_compression', 'Off');
    }   
    
    // Send Headers
    header('Content-Type: ' . $mime_type);
    header('Content-Disposition: attachment; filename="' . $filename . '"');
    header('Content-Transfer-Encoding: binary');
    header("Cache-Control: must-revalidate");
    header("Content-Description: File Transfer"); 
    header('Content-Length: ' . filesize($file));
    header('Expires: 0');
    header('Pragma: public');
    readfile($file);
?>
Medlem sedan juli 2004144 inlägg
#6

Det kan vara tecken som är skrivna i filens header. Det brukar isf fungera att copypasta koden till ett nytt textdokument, i tex anteckningar, och spara om.

Sen är det ju en inställning på klientsidan som styr om det ska laddas ner eller öppnas i läsaren?

288 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
144 ms — deklarationer (db)
0 ms — hämta statistik (cache)
141 ms — hämta tråd, inlägg och bilagor (db)
127 ms — ändringar (db)