Αποστολή multipart/formdata με jQuery.ajax
Έχω ένα πρόβλημα με την αποστολή ενός αρχείου σε ένα PHP-script από την πλευρά του διακομιστή χρησιμοποιώντας την jQuery's ajax-function.
Είναι δυνατόν να λάβω τη λίστα αρχείων με το $('#fileinput').attr('files')
, αλλά πώς είναι δυνατόν να στείλω αυτά τα δεδομένα στον διακομιστή; Ο πίνακας που προκύπτει ($_POST
) στο php-script από την πλευρά του διακομιστή είναι 0 (NULL
) όταν χρησιμοποιείται το file-input.
Ξέρω ότι είναι δυνατό (αν και δεν βρήκα μέχρι τώρα λύσεις jQuery, μόνο κώδικα Prototye (http://webreflection.blogspot.com/2009/03/safari-4-multiple-upload-with-progress.html)).
Αυτό φαίνεται να είναι σχετικά καινούργιο, οπότε μην αναφέρετε ότι το ανέβασμα αρχείων θα ήταν αδύνατο μέσω XHR/Ajax, γιατί σίγουρα λειτουργεί'ς.
Χρειάζομαι τη λειτουργικότητα στο Safari 5, το FF και το Chrome θα ήταν ωραία αλλά δεν είναι απαραίτητα.
Ο κώδικάς μου προς το παρόν είναι: Ο κώδικας μου είναι ο εξής:
$.ajax({
url: 'php/upload.php',
data: $('#file').attr('files'),
cache: false,
contentType: 'multipart/form-data',
processData: false,
type: 'POST',
success: function(data){
alert(data);
}
});
Ξεκινώντας από τον Safari 5/Firefox 4, είναι πιο εύκολο να χρησιμοποιήσετε την κλάση
FormData
:Έτσι τώρα έχετε ένα αντικείμενο
FormData
, έτοιμο να σταλεί μαζί με το XMLHttpRequest.Είναι απαραίτητο να ορίσετε την επιλογή
contentType
σεfalse
, αναγκάζοντας την jQuery να μην προσθέσει μια επικεφαλίδαContent-Type
για εσάς, διαφορετικά, η συμβολοσειρά ορίου θα λείπει από αυτήν. Επίσης, πρέπει να αφήσετε τη σημαίαprocessData
σε false, διαφορετικά, η jQuery θα προσπαθήσει να μετατρέψει ταFormData
σας σε συμβολοσειρά, πράγμα που θα αποτύχει.Μπορείτε τώρα να ανακτήσετε το αρχείο στην PHP χρησιμοποιώντας:
(Υπάρχει μόνο ένα αρχείο, το
file-0
, εκτός αν έχετε καθορίσει το χαρακτηριστικόmultiple
στην είσοδο του αρχείου σας, οπότε οι αριθμοί θα αυξάνονται με κάθε αρχείο).Χρησιμοποιώντας το FormData emulation για παλαιότερα προγράμματα περιήγησης
Δημιουργία FormData από μια υπάρχουσα φόρμα
Αντί για χειροκίνητη επανάληψη των αρχείων, το αντικείμενο FormData μπορεί επίσης να δημιουργηθεί με τα περιεχόμενα ενός υπάρχοντος αντικειμένου φόρμας:
Χρησιμοποιήστε έναν εγγενή πίνακα της PHP αντί για έναν μετρητή
Απλά ονομάστε τα στοιχεία του αρχείου σας με τον ίδιο τρόπο και τελειώστε το όνομα σε παρένθεση:
$_FILES['file']
θα είναι τότε ένας πίνακας που θα περιέχει τα πεδία μεταφόρτωσης αρχείων για κάθε αρχείο που μεταφορτώνεται. Στην πραγματικότητα προτείνω αυτή τη λύση σε σχέση με την αρχική μου λύση, καθώς είναι απλούστερη στην επανάληψη.Ήθελα απλώς να προσθέσω κάτι στη σπουδαία απάντηση του Raphael's. Να πώς μπορείτε να κάνετε την PHP να παράγει το ίδιο
$_FILES
, ανεξάρτητα από το αν χρησιμοποιείτε JavaScript για την υποβολή.Φόρμα HTML:
Η PHP παράγει αυτό το
$_FILES
, όταν υποβάλλεται χωρίς JavaScript:Μόλις έφτιαξα αυτή τη λειτουργία με βάση κάποιες πληροφορίες που διάβασα.
Χρησιμοποιήστε την όπως και τη χρήση της
.serialize()
, αντί να βάζετε απλά.serializefiles();
.