Περισσότερα
application/x-www-form-urlencoded ή multipart/form-data?
Στο HTTP υπάρχουν δύο τρόποι για την αποστολή δεδομένων POST: application/x-www-form-urlencoded
και multipart/form-data
. Καταλαβαίνω ότι οι περισσότεροι φυλλομετρητές είναι σε θέση να ανεβάσουν αρχεία μόνο εάν χρησιμοποιείται η μορφή multipart/form-data
. Υπάρχει κάποια πρόσθετη καθοδήγηση για το πότε πρέπει να χρησιμοποιείται ένας από τους τύπους κωδικοποίησης σε ένα πλαίσιο API (χωρίς να εμπλέκεται πρόγραμμα περιήγησης); Αυτό θα μπορούσε π.χ. να βασίζεται σε:
- μέγεθος δεδομένων
- ύπαρξη μη ASCII χαρακτήρων
- ύπαρξη (μη κωδικοποιημένων) δυαδικών δεδομένων
- την ανάγκη μεταφοράς πρόσθετων δεδομένων (όπως το όνομα αρχείου)
Βασικά δεν βρήκα καμία επίσημη καθοδήγηση στο διαδίκτυο σχετικά με τη χρήση των διαφόρων τύπων περιεχομένου μέχρι στιγμής.
1262
3
TL;DR
Σύνοψη: αν έχετε να μεταδώσετε δυαδικά (μη αλφαριθμητικά) δεδομένα (ή ωφέλιμο φορτίο σημαντικού μεγέθους), χρησιμοποιήστε το
multipart/form-data
. Διαφορετικά, χρησιμοποιήστεapplication/x-www-form-urlencoded
.Οι τύποι MIME που αναφέρετε είναι οι δύο επικεφαλίδες
Content-Type
για αιτήσεις HTTP POST που πρέπει να υποστηρίζουν οι πράκτορες-χρήστες (browsers). Ο σκοπός και των δύο αυτών τύπων αιτήσεων είναι η αποστολή μιας λίστας ζευγών ονόματος/τιμής στον διακομιστή. Ανάλογα με τον τύπο και την ποσότητα των δεδομένων που μεταδίδονται, η μία από τις μεθόδους θα είναι πιο αποτελεσματική από την άλλη. Για να καταλάβετε το γιατί, πρέπει να εξετάσετε τι κάνει η καθεμία από αυτές κάτω από τα καλύμματα.Για την
application/x-www-form-urlencoded
, το σώμα του μηνύματος HTTP που αποστέλλεται στον διακομιστή είναι ουσιαστικά ένα τεράστιο αλφαριθμητικό ερωτήματος -- τα ζεύγη ονόματος/τιμής διαχωρίζονται με την τελεία και παύλα (&
) και τα ονόματα διαχωρίζονται από τις τιμές με το σύμβολο ισότητας (=
). Ένα παράδειγμα θα ήταν: ,MyVariableOne=ValueOne&MyVariableTwo=ValueTwo
Σύμφωνα με τις προδιαγραφές:
Οι μη αλφαριθμητικοί χαρακτήρες αντικαθίστανται από `%HH', ένα σύμβολο του ποσοστού και δύο δεκαεξαδικά ψηφία που αντιπροσωπεύουν τον κωδικό ASCII του χαρακτήρα.
Αυτό σημαίνει ότι για κάθε μη αλφαριθμητικό byte που υπάρχει σε μια από τις τιμές μας, θα χρειαστούν τρία bytes για να το αναπαραστήσουμε. Για μεγάλα δυαδικά αρχεία, ο τριπλασιασμός του ωφέλιμου φορτίου θα είναι εξαιρετικά αναποτελεσματικός.
Σε αυτό το σημείο έρχεται το
multipart/form-data
. Με αυτή τη μέθοδο μετάδοσης ζευγών ονόματος/τιμής, κάθε ζεύγος αναπαρίσταται ως ένα "μέρος" σε ένα μήνυμα MIME (όπως περιγράφεται σε άλλες απαντήσεις). Τα μέρη διαχωρίζονται από ένα συγκεκριμένο όριο συμβολοσειράς (που επιλέγεται ειδικά έτσι ώστε αυτή η οριακή συμβολοσειρά να μην εμφανίζεται σε κανένα από τα ωφέλιμα φορτία "value"). Κάθε μέρος έχει το δικό του σύνολο επικεφαλίδων MIME, όπωςContent-Type
, και ιδιαίτεραContent-Disposition
, οι οποίες μπορούν να δώσουν σε κάθε μέρος το "όνομά του."Το κομμάτι αξίας κάθε ζεύγους ονόματος/τιμής είναι το ωφέλιμο φορτίο κάθε μέρους του μηνύματος MIME. Το MIME spec μας δίνει περισσότερες επιλογές κατά την αναπαράσταση του ωφέλιμου φορτίου τιμών -- μπορούμε να επιλέξουμε μια πιο αποδοτική κωδικοποίηση δυαδικών δεδομένων για να εξοικονομήσουμε εύρος ζώνης (π.χ. base 64 ή ακόμα και raw binary).Γιατί να μην χρησιμοποιείτε πάντα το
multipart/form-data
; Για σύντομες αλφαριθμητικές τιμές (όπως οι περισσότερες φόρμες ιστού), η επιβάρυνση από την προσθήκη όλων των επικεφαλίδων MIME πρόκειται να υπερκαλύψει σημαντικά οποιαδήποτε εξοικονόμηση από την αποδοτικότερη δυαδική κωδικοποίηση.Δεν νομίζω ότι το HTTP περιορίζεται σε POST σε multipart ή x-www-form-urlencoded. Η επικεφαλίδα [Content-Type Header][1] είναι ορθογώνια για τη μέθοδο HTTP POST (μπορείτε να συμπληρώσετε τον τύπο MIME που σας ταιριάζει). Αυτό ισχύει και για τις τυπικές διαδικτυακές εφαρμογές που βασίζονται στην αναπαράσταση HTML (π.χ. το json payload έγινε πολύ δημοφιλές για τη μετάδοση του ωφέλιμου φορτίου για αιτήματα ajax).
Όσον αφορά το Restful API μέσω HTTP, οι πιο δημοφιλείς τύποι περιεχομένου με τους οποίους ήρθα σε επαφή είναι οι application/xml και application/json.
application/xml:
Συμφωνώ με πολλά από αυτά που είπε ο Manuel. Στην πραγματικότητα, τα σχόλιά του αναφέρονται σε αυτό το url...
http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
... το οποίο αναφέρει:
Ωστόσο, για μένα αυτό εξαρτάται από την υποστήριξη εργαλείων/πλαισίων.
Αν έχετε μια σαφή ιδέα για τους χρήστες σας και για το πώς θα χρησιμοποιήσουν το API σας, τότε αυτό θα σας βοηθήσει να αποφασίσετε. Αν κάνετε το ανέβασμα αρχείων δύσκολο για τους χρήστες του API σας, τότε θα απομακρυνθούν, και εσείς θα ξοδέψετε πολύ χρόνο για την υποστήριξή τους.
Δευτερευόντως, θα πρέπει να ληφθεί υπόψη η υποστήριξη των εργαλείων που ΕΣΕΙΣ διαθέτετε για τη συγγραφή του API σας και το πόσο εύκολο είναι για εσάς να προσαρμόσετε τον ένα μηχανισμό μεταφόρτωσης σε σχέση με τον άλλο.