que method form example data html http-headers

html - method - ¿Qué significa enctype=''multipart/form-data''?



multipart/form-data c# (8)

¿Qué significa enctype=''multipart/form-data'' en un formulario HTML y cuándo debemos usarlo?


cuando deberiamos usarlo

La respuesta de Quentin es correcta: use multipart/form-data si el formulario contiene una carga de archivo, y application/x-www-form-urlencoded otra manera, que es la enctype predeterminada si omite enctype .

Voy a:

  • añadir algunas referencias HTML5 más
  • explique por qué tiene razón con un formulario enviar ejemplo

Referencias HTML5

Hay tres posibilidades para enctype :

Cómo generar los ejemplos.

Una vez que vea un ejemplo de cada método, se vuelve obvio cómo funcionan y cuándo debe usar cada uno.

Puedes producir ejemplos usando:

Guarde el formulario en un archivo .html mínimo:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"/> <title>upload</title> </head> <body> <form action="http://localhost:8000" method="post" enctype="multipart/form-data"> <p><input type="text" name="text1" value="text default"> <p><input type="text" name="text2" value="a&#x03C9;b"> <p><input type="file" name="file1"> <p><input type="file" name="file2"> <p><input type="file" name="file3"> <p><button type="submit">Submit</button> </form> </body> </html>

Establecemos el valor de texto predeterminado a a&#x03C9;b , lo que significa aωb porque ω es U+03C9 , que son los bytes 61 CF 89 62 en UTF-8.

Crea archivos para subir:

echo ''Content of a.txt.'' > a.txt echo ''<!DOCTYPE html><title>Content of a.html.</title>'' > a.html # Binary file containing 4 bytes: ''a'', 1, 2 and ''b''. printf ''a/xCF/x89b'' > binary

Ejecute nuestro pequeño servidor de eco:

while true; do printf '''' | nc -l 8000 localhost; done

Abra el HTML en su navegador, seleccione los archivos y haga clic en enviar y verifique el terminal.

nc imprime la solicitud recibida.

Probado en: Ubuntu 14.04.3, nc BSD 1.105, Firefox 40.

multipart / form-data

Firefox envió:

POST / HTTP/1.1 [[ Less interesting headers ... ]] Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150 Content-Length: 834 -----------------------------735323031399963166993862150 Content-Disposition: form-data; name="text1" text default -----------------------------735323031399963166993862150 Content-Disposition: form-data; name="text2" aωb -----------------------------735323031399963166993862150 Content-Disposition: form-data; name="file1"; filename="a.txt" Content-Type: text/plain Content of a.txt. -----------------------------735323031399963166993862150 Content-Disposition: form-data; name="file2"; filename="a.html" Content-Type: text/html <!DOCTYPE html><title>Content of a.html.</title> -----------------------------735323031399963166993862150 Content-Disposition: form-data; name="file3"; filename="binary" Content-Type: application/octet-stream aωb -----------------------------735323031399963166993862150--

Para el archivo binario y el campo de texto, los bytes 61 CF 89 62 ( aωb en UTF-8) se envían literalmente. Podrías verificar que con nc -l localhost 8000 | hd nc -l localhost 8000 | hd , que dice que los bytes:

61 CF 89 62

fueron enviados ( 61 == ''a'' y 62 == ''b'').

Por lo tanto está claro que:

  • Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266 Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266 establece el tipo de contenido en multipart/form-data y dice que los campos están separados por el dado cadena de boundary .

  • cada campo obtiene algunos subencabezados antes de sus datos: Content-Disposition: form-data; , el name del campo, el filename del filename , seguido de los datos.

    El servidor lee los datos hasta la siguiente cadena de límite. El navegador debe elegir un límite que no aparecerá en ninguno de los campos, por lo que el límite puede variar entre solicitudes.

    Debido a que tenemos un límite único, no es necesaria la codificación de los datos: los datos binarios se envían tal como están.

    TODO: ¿cuál es el tamaño de límite óptimo ( log(N) que apuesto) y el nombre / tiempo de ejecución del algoritmo que lo encuentra? Consultado en: https://cs.stackexchange.com/questions/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequences

  • Content-Type es determinado automáticamente por el navegador.

    ¿Cómo se determina exactamente cómo se preguntó? ¿Cómo se determina el tipo de mime de un archivo cargado por el navegador?

aplicación / x-www-form-urlencoded

Ahora cambie el enctype a application/x-www-form-urlencoded , vuelva a cargar el navegador y vuelva a enviar.

Firefox envió:

POST / HTTP/1.1 [[ Less interesting headers ... ]] Content-Type: application/x-www-form-urlencoded Content-Length: 51 text1=text+default&text2=a%CF%89b&file1=a.txt&file2=a.html&file3=binary

Claramente, los datos del archivo no se enviaron, solo los nombres de base. Así que esto no puede ser usado para archivos.

En cuanto al campo de texto, vemos que los caracteres imprimibles habituales como a y b se enviaron en un byte, mientras que los no imprimibles como 0xCF y 0x89 tomaron 3 bytes cada uno: %CF%89 !

Comparación

La carga de archivos a menudo contiene muchos caracteres no imprimibles (por ejemplo, imágenes), mientras que las formas de texto casi nunca lo hacen.

De los ejemplos hemos visto que:

  • multipart/form-data : agrega unos pocos bytes de sobrecarga de límite al mensaje, y debe pasar algún tiempo en calcularlo, pero envía cada byte en un byte.

  • application/x-www-form-urlencoded : tiene un límite de un solo byte por campo ( & ), pero agrega un factor de sobrecarga lineal de 3x por cada carácter no imprimible.

Por lo tanto, incluso si pudiéramos enviar archivos con application/x-www-form-urlencoded , no application/x-www-form-urlencoded hacerlo porque es muy ineficiente.

Pero para los caracteres imprimibles que se encuentran en los campos de texto, no importa y genera menos sobrecarga, por lo que simplemente lo usamos.


Al enviar un formulario, está tratando de decirle a su navegador que envíe a través del protocolo HTTP un mensaje en la red adecuadamente envuelto en una estructura de mensajes de protocolo TCP / IP. Al enviar datos, puede utilizar métodos POST o GET para enviar datos mediante el protocolo HTTP. POST le dice a su navegador que cree un mensaje HTTP y ponga todo el contenido en el cuerpo del mensaje (una forma muy útil de hacer las cosas, más segura y flexible). GET tiene algunas restricciones sobre la representación y la longitud de los datos.

Indicando lo que envias

Al enviar un archivo, es necesario informar al protocolo HTTP que está enviando un archivo que tiene varias características e información dentro de él. De esta manera, es posible enviar datos constantemente al receptor y dejar que abra el archivo con el formato actual y así sucesivamente ... Este es un requisito del protocolo HTTP como se muestra here

No puede enviar archivos usando los parámetros de enctype predeterminados porque su receptor puede tener problemas para leerlos (considere que un archivo es un descriptor de algunos datos para un sistema operativo específico, si ve las cosas de esta manera, tal vez comprenda por qué es tan importante para especificar un enctype diferente para los archivos).

No olvides la seguridad

Esta forma de hacer las cosas también garantiza que algunos algoritmos de seguridad funcionen en sus mensajes. Esta información también es utilizada por los enrutadores de nivel de aplicación para actuar como buenos cortafuegos para datos externos.

Bueno, como puedes ver, no es una estupidez usar un enctype específico para archivos.


Cuando realiza una solicitud POST, tiene que codificar los datos que forman el cuerpo de la solicitud de alguna manera.

Los formularios HTML proporcionan tres métodos de codificación.

  • application/x-www-form-urlencoded (el valor predeterminado)
  • multipart/form-data
  • text/plain

Se estaba trabajando en agregar application/json , pero se ha abandonado.

Los detalles de los formatos no son importantes para la mayoría de los desarrolladores. Los puntos importantes son:

Cuando está escribiendo el código del lado del cliente, todo lo que necesita saber es usar multipart/form-data cuando su formulario incluya cualquier elemento <input type="file"> .

Cuando escriba el código del lado del servidor: use una biblioteca de manejo de formularios CGI->param (por ejemplo, CGI->param Perl o la expuesta por $_POST superglobal de PHP) y se hará cargo de las diferencias por usted. No se moleste en tratar de analizar la entrada en bruto recibida por el servidor.

Nunca use text/plain .

Si está escribiendo (o depurando) una biblioteca para analizar o generar los datos sin procesar, entonces debe comenzar a preocuparse por el formato. También es posible que desee saberlo por interés.

application/x-www-form-urlencoded es más o menos lo mismo que una cadena de consulta al final de la URL.

multipart/form-data es significativamente más complicado, pero permite que se incluyan archivos completos en los datos. Un ejemplo del resultado se puede encontrar en la especificación HTML 4 .

HTML / HTML introduce el text/plain y es útil solo para la depuración de la especificación : no se pueden interpretar de manera confiable por computadora , y yo diría que los otros se combinaron con herramientas (como la pestaña Red en las herramientas para desarrolladores de la mayoría de los navegadores) ) son mejores para eso).


Establezca el atributo del método en POST porque el contenido del archivo no se puede colocar dentro de un parámetro de URL usando un formulario.

Establezca el valor de enctype en multipart / form-data porque los datos se dividirán en varias partes, una para cada archivo más una para el texto del cuerpo del formulario que se puede enviar con ellos.


Por lo general, esto ocurre cuando tiene un formulario POST que necesita tomar una carga de archivo como datos ... esto le dirá al servidor cómo codificará los datos transferidos, en ese caso no se codificará porque solo se transferirá y cargará Los archivos en el servidor, como por ejemplo al cargar una imagen o un pdf


enctype=''multipart/form-data'' significa que no se codificarán caracteres. es por eso que este tipo se usa al cargar archivos al servidor.
Por lo tanto, multipart/form-data se usa cuando un formulario requiere datos binarios, como el contenido de un archivo, para ser cargados


enctype=''multipart/form-data es un tipo de codificación que permite enviar archivos a través de un POST . Sencillamente, sin esta codificación, los archivos no se pueden enviar a través de POST .

Si desea permitir que un usuario cargue un archivo a través de un formulario, debe usar este enctype .


  • El atributo enctype ( ENC ode TYPE ) especifica cómo se deben codificar los datos de formulario al enviarlos al servidor.
  • multipart / form-data es uno de los valores del atributo enctype, que se usa en el elemento form que tiene una carga de archivo. multiparte significa que los datos de formulario se dividen en múltiples partes y se envían al servidor.
    • Parte de la metáfora: un documento HTML tiene dos partes : una cabeza y un cuerpo.