Tohle je věc, která mě kdysi před mnoha lety hodně vytáčela. Velké soubory zákazníci nahrávají odjakživa a trpělivost mají jen minimální. Nedařilo se mi průběžný status uploadu tenkrát nijak rozběhat. Dnes už je naštěstí relativně jednoduché o stavu uploadu uživatele informovat. Tedy alespoň s využitím kvalitního skriptu to jde zařídit poměrně snadno…
Existuje řada javascriptových řešení. Hned napoprvé jsem si oblíbil simpleUpload. http://simpleupload.michaelcbrook.com
Implementace je samozřejmě dostatečně popsána na webu autora skriptu, avšak aby to našinec nemusel objevovat stále dokola, je dobré mít po ruce zjednodušený postup.
- Jako první je dobré skript z výše uvedeného webu stáhnout a vložit do hlavičky stránky: <script src=“vendor/simpleupload/simpleUpload.min.js“ type=“text/javascript“></script>
- Hned za tím umístit následující kód:
1234567891011121314151617181920212223242526272829303132333435363738394041<script type="text/javascript">$(document).ready(function(){$('input[type=file]').change(function(){$(this).simpleUpload("/ajax/upload.php", {allowedExts: ["pdf", "zip", "rar"],allowedTypes: ["application/pdf", "application/zip", "application/x-zip", "application/x-zip-compressed", "application/octet-stream", "application/rar", "application/x-rar-compressed"],maxFileSize: 500000000, //500 MBstart: function(file){//upload started$('#filename').html(file.name);$('#progress').html("");$('#progressBar').width(0);},progress: function(progress){//received progress$('#progress').html("Průběh: " + Math.round(progress) + "%");$('#progressBar').width(progress + "%");},success: function(data){//upload successful$('#progress').html("<span style=\"color:green;\">Soubor byl úspěšně uložen.</a><br>");$("input[name=nazev_souboru]").val(data);},error: function(error){//upload failed$('#progress').html("<span style=\"color:red;\">CHYBA!</a><br>" + error.name + ": " + error.message);}});});});</script>
Upload bude zahájen ihned po prokliknutí výběru souboru z disku a je tedy nezávislý na formuláři.
Jak propojit uploadovaný soubor s formulářem si ukážeme za chvíli. Má v tom prsty zejména řádek č. 28, kam předáme data (v našem případě název souboru v podobě v jaké bude uložen na severu) když dojde k úspěšnému nahrání. input[name=nazev_souboru] je selektor. Ačkoliv to ještě nejde poznat, přiřadíme jím val(data) hidden prvku formuláře s názvem nazev_souboru. - Ve formuláři budou tři div tagy pro zobrazování průběhu uploadu:
<div id=“filename“></div> … zde budeme zobrazovat název souboru
<div id=“progress“></div> … zde slovně popíšeme průběh
<div id=“progressBar“></div> … a zde zobrazíme procentuální stav uploadu. Povšimněte si, že v kódu z bodu 2. se jednoduše pracuje s těmito tagy pomocí selektorů #filename, #progress a #progressBar. - Samotný upload lze zahájit kliknutím na tlačítko Procházet … , které ve formuláři zobrazíme pomocí kódu:
<input type=“file“ name=“uploaded_file“>
Takže při změně (při vybrání souboru z disku) se spustí funkce: $(‚input[type=file]‘).change(function(){ … }) - Bylo by dobré ještě trochu osvětlit řádky 8 až 10 z bodu 2.
allowedExts … (allowed Extensions) … můžete nastavit samozřejmě libovolné přípony; v našem případě umožňujeme nahrát pouze archivy zip a rar
Aby nás někdo neošálil, testujeme ještě mime typ souboru. Povolené mime typy jsou v allowedTypes. V případě pdf je to jednoduché … stačí uvést application/pdf. Avšak zip a rar jsou komplikovanější. Je zapotřebí uvést více variant, aby nedošlo k odmítnutí souborů zazipovaných/zararovaných nestandardním způsobem. - $(this).simpleUpload(„/ajax/upload.php“, { … })
Spustí skript upload.php na serveru uložený v adresáři ajax.
Tento skript řeší pouze uložení náhraného souboru a sice například takto:
123456789101112131415161718<?php/* skript je volán ajaxem ze stránky, na které je formulář, resp. tlačítko pro upload souboru */if(!empty($_FILES['uploaded_file'])){$path = "uploads/";$uploadedName = $_FILES['uploaded_file']['name'];$ext = strtolower(substr($uploadedName, strripos($uploadedName, '.')+1));$filename = round(microtime(true)).mt_rand().'.'.$ext;if(move_uploaded_file($_FILES['uploaded_file']['tmp_name'], $path.$filename)) {echo $filename;} else{echo "Během nahrávání souboru se vyskytla chyba!";}}?>
Do proměné $ext uložíme příponu, následně vygenerujeme nový název souboru, příponu přidáme a upload souboru dovršíme příkazem move_uploaded_file() .
Nový název souboru předáme zpět javascriptu příkazem echo $filename;
To jsou právě data předávaná při úspěchu na řádku č. 28 v bodě 2.
(Neúspěch při nahrávání zde není dořešen.) - Jak tedy vypadá samotný formulář?
12345678910111213<form action="https://www.vasweb.cz/poptavka/" method="post"><input type="text" name="jmeno"><div id="filename"></div><div id="progress"></div><div id="progressBar"></div>Zde můžete nahrát Váš soubor a sice <b>pdf</b>, <b>zip</b> nebo <b>rar</b>. Maximální velikost je 500 MB. Formulář odešlete až po dokončení náhrávání souboru!<input type="file" name="uploaded_file"><input type="hidden" name="nazev_souboru" value="0"><input type="submit" value="Odeslat"></form>
Povšimněte si, že není potřeba uvádět ve formulářimultipart/form-data
Jak vypadá upload vizuálně si můžete vyzkoušet na webu autora skriptu.