application/x-www-form-urlencoded o multipart/form-data?
En HTTP hay dos formas de enviar datos por POST: application/x-www-form-urlencoded
y multipart/form-data
. Tengo entendido que la mayoría de los navegadores sólo son capaces de cargar archivos si se utiliza multipart/form-data
. ¿Existe alguna orientación adicional sobre cuándo utilizar uno de los tipos de codificación en un contexto de API (sin navegador)? Esto podría, por ejemplo, basarse en:
- el tamaño de los datos
- la existencia de caracteres no ASCII
- la existencia de datos binarios (no codificados)
- la necesidad de transferir datos adicionales (como el nombre del archivo)
Básicamente, hasta ahora no he encontrado ninguna orientación formal en la web sobre el uso de los diferentes tipos de contenido.
1262
3
TL;DR
Resumen; si tiene datos binarios (no alfanuméricos) (o una carga útil de tamaño significativo) para transmitir, utilice
multipart/form-data
. En caso contrario, utiliceapplication/x-www-form-urlencoded
.Los tipos MIME que mencionas son las dos cabeceras
Content-Type
para las peticiones HTTP POST que los agentes de usuario (navegadores) deben soportar. El propósito de estos dos tipos de peticiones es enviar una lista de pares nombre/valor al servidor. Dependiendo del tipo y la cantidad de datos que se transmitan, uno de los métodos será más eficiente que el otro. Para entender por qué, hay que ver lo que hace cada uno bajo cuerda.En el caso de
application/x-www-form-urlencoded
, el cuerpo del mensaje HTTP que se envía al servidor es esencialmente una gigantesca cadena de consulta: los pares nombre/valor se separan con el signo de amperio (&
), y los nombres se separan de los valores con el símbolo de igualdad (=
). Un ejemplo de esto sería:MiVariableUna=ValorUna&MiVariableDos=ValorDos
Según la especificación:
Esto significa que por cada byte no alfanumérico que exista en uno de nuestros valores, se necesitarán tres bytes para representarlo. Para los archivos binarios grandes, triplicar la carga útil va a ser muy ineficiente.
Ahí es donde entra
multipart/form-data
. Con este método de transmisión de pares nombre/valor, cada par se representa como una "parte" en un mensaje MIME (como se describe en otras respuestas). Las partes están separadas por una cadena límite particular (elegida específicamente para que esta cadena límite no aparezca en ninguna de las cargas útiles de "valor"). Cada parte tiene su propio conjunto de cabeceras MIME comoContent-Type
, y particularmenteContent-Disposition
, que pueden dar a cada parte su "nombre". La pieza de valor de cada par nombre/valor es la carga útil de cada parte del mensaje MIME. La especificación MIME nos da más opciones a la hora de representar la carga útil del valor: podemos elegir una codificación más eficiente de los datos binarios para ahorrar ancho de banda (por ejemplo, base 64 o incluso binario crudo).¿Por qué no usar
multipart/form-data
todo el tiempo? Para valores alfanuméricos cortos (como la mayoría de los formularios web), la sobrecarga de añadir todas las cabeceras MIME va a superar significativamente cualquier ahorro de una codificación binaria más eficiente.No creo que HTTP esté limitado a POST en multipartes o x-www-form-urlencoded. El [Encabezado de Tipo de Contenido][1] es ortogonal al método HTTP POST (puedes rellenar el tipo MIME que te convenga). Este es también el caso de las típicas aplicaciones web basadas en la representación HTML (por ejemplo, la carga útil json se hizo muy popular para transmitir la carga útil de las peticiones ajax).
En lo que respecta a Restful API sobre HTTP, los tipos de contenido más populares con los que he entrado en contacto son application/xml y application/json.
application/xml:
Estoy de acuerdo con mucho de lo que ha dicho Manuel. De hecho, sus comentarios se refieren a esta url...
http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
... que dice:
Sin embargo, para mí se reduciría al soporte de la herramienta/marco.
Si tienes una idea clara de tus usuarios y de cómo van a utilizar tu API, eso te ayudará a decidir. Si haces que la carga de archivos sea difícil para tus usuarios de la API, se alejarán, y tú gastarás mucho tiempo en darles soporte.
En segundo lugar, está el soporte de la herramienta que TÚ tienes para escribir tu API y lo fácil que es para ti acomodar un mecanismo de carga sobre el otro.