Come da titolo sto cercando di implementare l'upload di files, tipicamente immagini, inviando i dati al server con una transazione AJAX e la cosa si sta rivelando più complicata del previsto.
Premesso che uso praticamente da sempre AJAX (nativo... mi scrivo a manina il codice senza ricorrere a JQuery o altro di simile) non l'ho mai fatto, appunto, per l'upload di files ma solo per interrogare il database.
Prima di iniziare a scrivere il codice mi sono documentato in rete e praticamente tutti gli esempi cho ho trovato si appoggiano alla classe Javascript "FormData". Il codice che utilizzo è sostanzialmente quello che segue.
Codice HTML:
<input type="file" id="uploadFile" name="uploadFile" />
<br />
<input type="text" id="uploadDescription" value="" title="Descrizione dell'immagine" />
<br />
<input type="button" style="background-color: grey; width: 60px;" value="Invia" onclick="javascript:uploadUserImage();" title="Fai clic qui per inviare l'immagine al server" />
Il campo con id "uploadFile" apre ovviamente la select files del browser.
Il campo con id "uploadDescription" consente all'utente di inserire una breve descrizione che vorrei salvare nel database.
Il butto non effettua il submit, ovviamente, ma invoca la seguente funzione:
Codice:
function uploadUserImage(){
// ottengo i valori immessi dall'utente
var file = document.getElementById("uploadFile");
var description = document.getElementById("uploadDescription").value;
// istanzio un oggetto della classe FormData
var formData = new FormData();
// aggiungo al FormData i campi
formData.append("file", file.files[0]);
formData.append("description", description);
// dichiaro lo script server-side a cui inviare i dati
var ajaxFilePath = "./uploadUserImage.php";
// istanzio un oggetto per la trasmissione dati su protocollo HTTP
var client = new XMLHttpRequest;
// apro la connessione col server
client.open('POST', ajaxFilePath, true);
// informo il server sulla tipologia di dati
client.setRequestHeader("Content-Type", "multipart/form-data");
// dichiaro un gestore della risposta che riceverò dal server
client.onreadystatechange = handleUploadUserImage;
// trasmetto fisicamente i dati
client.send(formData);
}
Lo script PhP che riceve (o meglio... che DOVREBBE ricevere i dati) fa sostanzialmente quanto segue
Codice PHP:
// variabile per eventuali messaggi di errore
$errMsg = "";
// verifica che sia stato trasmesso il file
if (!isset($_FILES["file"]) ){
$errMsg .= "manca il file\n";
}
if (!isset($_POST["description"])){
$errMsg .= "manca la descizione\n";
}
// se i dati mancano interrompo l'elaborazione...
if ($errMsg <> ""){
die($errMsg);
}
// altrimenti proseguo con l'elaborazione
Lo script termina sempre con il messaggio di errore, visualizzato dall'handler javascript della risposta del server.
Evito di dettagliare i vari tentativi che ho fatto. Se trasmetto dati di normali campi testo, checkbox o select (impostando diversamente il content-type negli headers) tutto bene, se trasmetto un file niente da fare...
Il codice che ho postato è molto compatto, in quello reale ci sono tutte le gestioni dello status della transazione, la gestione della risposta, i controlli di sicurezza lato server... ovviamente ho provato anche il codice postato...
Qualcuno sa dirmi dove sbaglio? grazie!