Letöltés erőltetése ismert fájltípus esetében is

Felmerült ma délután egy kérdés és mivel hirtelen én sem tudtam rá a pontos választ, utánanéztem. A kérdés az alábbi volt: hogy lehet a böngészőt letöltési ablak feldobására kényszeríteni még olyan fájltípusok esetében is, amikor egyébként a böngésző, vagy egy másik program automatikusan megnyitná azt?

Álmos a rövid szőrű magyar vizsla

A példa kedvéért egy jpg fájlon próbáltam ki a módszert. A megoldás lényege egy apró PHP fájl amit a letöltésre felkínált fájllal egy könyvtárba kell elhelyezni. A PHP fájl tartalma ennyi lenne:

1
2
3
4
5
6
7
8
<?php
$file = str_replace('../','',$_GET['file']);
header ("Content-type: octet/stream");
header ("Content-disposition: attachment; filename=".$file.";");
header("Content-Length: ".filesize($file));
readfile($file);
exit;
?>

Ez a fenti kódot letoltes.php néven mentettem el a példában. Ez után az alábbi URL-lel lehet a fenti képet meghivatkozni, ha szeretnénk, hogy a képet mindenképpen letöltésre kínálja fel:

1
http://www.tutorial.hu/webszerkesztes/letoltes-eroltetese/letoltes.php?file=almos.jpg

A kép a hagyományos módon linkelve természetesen megjelenne a böngészőben:

1
http://www.tutorial.hu/webszerkesztes/letoltes-eroltetese/almos.jpg

14 HOZZÁSZÓLÁS

  1. Ha van egyébként más megoldás is, írjátok meg, én szívesen elolvasnám és szerintem a többi olvasó is örülne neki.

  2. Miért, ennek mi a veszélye? Ha csak annyi, hogy ezt a fájlt le lehet tölteni a szerverről, az nem gond, hiszen a kódja itt van a leírásban is.

  3. Hát, ha másik php fájlt ad meg, ahol mondjuk vannak olyan kódrészek, amik kritikusok a rendszerre nézve, az már necces.

  4. Mondjuk ha legalább beleraksz egy olyat, hogy

    1
    
    $file = str_replace('../','',$_GET['file']);

    Akkor azt elkerülöd, hogy kilépjen a mappából és nem fogja például a cms adatbázis configját tartalmazó php-t letölteni.

  5. Ez meg mindig nem az igazi, mert ha kitalalja valaki a konyvtarstrukturat akkor meg mindig hozzafer barmihez. Ilyen GET parameteres letoltest ugy erdemes kivitelezni, hogy van egy adott fajlhalmaz amibol le lehet tolteni. Ezt tarolhatod adatbazisban, vagy akar egy tombben. Esetleg meg ugy hogy a GET parameternek csak az utolso / jel utani reszet veszed figyelembe es prefixeled azzal a mappaval amiben a szabadon hozzaferheto fajlok vannak.

  6. Köszi, értem a problémát, szerencsére még akkor egyből le is vettem ezt a megoldást a szerverről, így itt nem lehet kihasználni. A fájltárolásos szűrés jó ötletnek tűnik, főleg ha ki lehet vitelezni mondjuk egy akármilyen nevű txt fájllal is, hogy ne kelljen esetleg 1-2 db fájl miatt adatbázisban és phpmyadmin-on turkálni. :)

  7. 
    

    A fenti peldaban csak a $file_list tombot kell kiegesziteni. Nem tul kenyelmes megoldas, de biztonsagos.

  8. hm… valamiert nem tudom a kodot beilleszteni :). talan igy.

    $file = str_replace('../','',$_GET['file']);
    $file_list = array('file1.jpg', 'file2.jpg');
    if(!in_array($file, $file_list))die('File not found.');
    header ("Content-type: octet/stream");
    header ("Content-disposition: attachment; filename=".$file.";");
    header("Content-Length: ".filesize($file));
    readfile($file);
    exit;

HOZZÁSZÓLOK A CIKKHEZ

Kérjük, írja be véleményét!
írja be ide nevét