T&R splet blog o spletnih storitvah. Razgaljamo tehnologijo!

reference spletnih strani
19th March

Shrani datoteko / Odpri datoteko dialog – download center (mime-type, Content-type, Content-Disposition)

Velikokrat se naredi, da bi želeli datoteko s strani PHP-ja predstaviti (ponuditi, servirati) tako, da bo brskalnik v vsakem primeru uporabnika vprašal kam želi to datoteko shraniti (ali takoj odpreti z Y programom, kar pomeni shraniti v začasni direktorij in nato odpreti to datoteko z izbranim programom). Problem, ki nastane tukaj je, da se brskalniki razlikujejo med sabo (kot vedno) in je težje napisati download skripto, ki vrača datoteke tako da brskalnik vedno vpraša uporabnika kaj naj naredi z datoteko.

Marsikje je moč prebrati, da se kot mime-type (defenicijo mime-type si preberite na dnu prispevka) vpiše application/download ali application/force-download, najde se tudi application/x-download in podobno. Kaj je s tem narobe? Zgoraj omenjeni tipi niso nikjer točno defenirani, torej bi si lahko izbrali tudi trsplet/mimetype. Drug problem nastane, ko datoteka namesto npr. application/pdf dobi application/force-download. Ko preberemo mimetype od datoteke s PHP-jem, naprimer v mojem primeru:

PHP:
  1. $mimetype = trim ( exec ('file -bi ' . escapeshellarg ( $filename) ) ) ;

dobimo nepravilni mime-type datoteke. Zato moramo za vsako datoteko uporabiti pravi mime-type in NE force-download ali kaj podobnega ko serviramo (podajamo) datoteke s PHP-jem. V primeru, da ne vemo mime-type določene datoteke je boljše oz. je nujno uporabiti application/octet-stream (defeniran v HTTP standardu) namesto application/x-download (ali katerikoli drugi poljubni mime-type tipi).

Po testiranju header nastavitev sem prišel do sledeče skripte:

PHP:
  1. header("Content-length: ".filesize($filename)); // s tem brskalnik lahko prikaže download bar (koliko še manjka do zaključka prenosa)
  2. header("Content-type: $mimetype"); // defeniramo mime-type
  3. header("Content-Disposition: attachment; filename=$originalFilename"); // podajmo drugačen ime datoteko kot je realen ime datotek na FTP-ju
  4. header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); // IE fix
  5. readfile($filename); // feof, fopen, fread je hitrejše

S sledečo skripto lahko s pomočjo PHP-ja serviramo datoteko tako, da bo brskalnik vedno ponudil Odpri / Shrani kot dialog. Zadeva deluje na IE 5.5, IE 6.0, IE 7.0, Firefox 2, Opera. Nagajal je le Safari (Win) in sicer noče ponuditi dialoga, vendar datoteko shrani pravilno na lokacijo, ki jo imamo izbrano kot privzeto lokacija za dol-vleči (download) v nastavitvah.

Skripta omogoča, da datoteko podamo skozi drugačno ime kot je na FTP-ju (Content-Disposition). Naprimer preberemo 3423042304234_testiram.pdf na FTP-ju in uporabniku datoteko serviramo kot Tole je testna datoteka.pdf. Zadeva deluje na vseh zgoraj omenjenih brskalnikih, tudi na Safari-ju.

Skripta pa ima še eno dodatno pozitivno lastnost in sicer, zadeva deluje tudi kot serviranje podatkov v okviru spletne strani (ne kot force download). Naprimer, če želimo dobiti sliko v HTML Img tag-u:

HTML:
  1. <img alt="Datoteke testiram.jpg ni bilo moč najti." src="download.php?file_id=ID" style="border: 0px none ;"/>

Zadeva deluje tudi v HTML Object tag-u:

HTML:
  1. <object width="300" height="400" type="application/pdf" data="download.php?file_id=ID">Datoteke: testiram.pdf ni bilo moč najti</object>

Tudi ta funkcionalnost deluje v vseh zgoraj omenjenih brskalnikih. Tako smo dobili preprosti download center.

Mime-type

"MIME types" are used to identify the type of information that a file contains. While the file extension .html is informally understood to mean that the file is an HTML page, there is no requirement that it mean this, and many HTML pages have different file extensions.

Da zagotovim vedno pravilen type glede na tip datoteko uporabljam vnaprej defenirane za moje standardne datoteke:

PHP:
  1. $mimeTypes  = array('pdf' => 'application/pdf', 'jpg' => 'image/jpeg', 'mpg' => 'application/binary', 'wmv' => 'video/x-ms-wmv', 'flv' => 'application/octet-stream', 'avi' => 'video/x-msvideo');
  2. $mimetype = $mimeTypes['jpg'];

Varnost:
Ko uporabljamo PHP za serviranje datotek moramo zelo paziti kako podamo skripti katero datoteko želimo. Če bi uporabili sledeč princip:

PHP:
  1. $filename = $_GET['filename'];
  2. readfile($filename);
  3.  
  4. //... kar kličemo po vdoru v naš strežnik saj lahko napadel preproste pokliče vašo PHP skripto,
  5. //ki skrbi za serviranje datotek in dobi katerikoli datoteko želi, naprimer:
  6. //Napadlec pokliče: http://spletnastran.com/download.php?filename=./constants.php
  7. $filename = $_GET['filename']; //./constants.php
  8. readfile("./constants.php"); // vsi podatki v constants.php bodo sedaj vidni napadalcu

Zato je najboljše uporabiti navezo z bazo. V klicu ne defeniramo točnega imena datoteke ampak le id datoteke, ki je zapisan v bazi (npr.: download.php?file_id=ID). S tem pa lahko tudi kontroliramo ali je datoteka vidna ali ne, naprimer (ne pozabite filtrirati $file_id):

MySQL:
  1. SELECT * FROM `files` WHERE `file_id`='$file_id' AND `visible`='1' LIMIT 0,1

Nato preverimo, če datoteka obstaja in če je vidna jo izpišemo drugače pa lahko vrnemo:

PHP:
  1. header("HTTP/1.0 404 Not Found");

Dodatne informacije:

Primer delovanja:

Zadeva ni bila testirana na večji količini uporabnikov zato je možno, da kje na kakšnem Y brskalniku X verzije zadeva ne deluje kot predvieno. V tem primeru mi prosim to sporočite. Hvala.

Deli s skupnostjo:

  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks

Podobni članki:

  1. PHP – kako ugotoviti tip datoteke (get file extension type)
  2. PHP – pošiljanje emaila – epošte – sending email – HTML Mime Mail
  3. HTML Mime Mail PHP – nastavljanje kodne tabele (charset – windows-1250 – UTF-8) – Outlook Express
  4. Spreminanje input type text v input type password – Javascript
  5. PHP – pretvorba Excel datoteke v .txt datoteko – Excel to txt converter
  6. Predogled PDF-ja – pretvorba PDF v jpeg s pomočjo PHP-ja
  7. Dinamično kreiranje / Upravljanje slik
  8. PHP – Kreiranje Excel datoteke – Pisanje v Excel datoteko – PHP – xls
  9. Uporabni HTML meta tagi – PHP header
  10. Preprosta skripta – kreiranje Excel datoteke iz PHP tabele/array

7x komentirano na “Shrani datoteko / Odpri datoteko dialog – download center (mime-type, Content-type, Content-Disposition)”

  1. Cobra je napisal:

    Samo nekaj bi priporočal na blogu,da daš demo primerke gor in ubistvu vidimo delovanje ipd..;)

  2. Roky je napisal:

    Pri večini stvari sem dal primerke gor, primer delovanja - preizkusite je ponavadi pod Datoteke sekcija. Bom dodal tudi za ta prispevek.

    Hvala za priporočilo.

  3. Roky je napisal:

    Sem dodal še primerek skripte.

  4. Cobra je napisal:

    Okej. Hvala ;)

  5. .: TRSplet - internetne storitve .: » Blog Archive » Dinamično kreiranje / Upravljanje slik je napisal:

    [...] - UTF-8 - Težave Roky - Šumniki - UTF-8 - Težave zaxy - Šumniki - UTF-8 - Težave Cobra - Shrani datoteko / Odpri dRoky - Shrani datoteko / Odpri dRoky - Iskalnikom in uporabnikomCobra - Iskalnikom in [...]

  6. .: TRSplet - internetne storitve .: » Blog Archive » Predogled PDF-ja - pretvorba PDF v jpeg s pomočjo PHP-ja je napisal:

    [...] Shrani datoteko / Odpri datoteko dialog - download center (mime-type, Content-type, Content-Disposit... [...]

  7. .: TRSplet - internetne storitve .: » Blog Archive » Uporabni HTML meta tagi - PHP header je napisal:

    [...] Shrani datoteko / Odpri datoteko dialog - download center (mime-type, Content-type, Content-Disposit... [...]

Dodaj komentar