When sending a file to the server it is necessary to use an encoding that allows sending binary data along with form data.
Normally a POST without files in the form has a body with the following format:
campo1=1234&campo2=Miguel&campo3=30
This format is identical to the query-string format in the URI.
Note that it would not be possible to send a binary file of this format unless it was transformed into some text format, such as base-64. But this is not the case as base-64 or any other text encoding would undoubtedly increase the size of the request.
For this there is an encoding format that allows the sending of binary data: multipart/form-data
.
Coding multipart/form-data
This encoding allows to transmit to the server the files in binary format. It is defined in the protocol HTTP 1.1 section 3.7.2 Multipart Types (rfc1867).
The encoding format consists of generating random separators, and separating each form field with this separator.
See an example of POST using this encoding: (example of this site)
POST /diretorio/arquivo HTTP/1.0
Host: www.dominio.com.br
Content-type: multipart/form-data, boundary=AaB03x
Content-Length: 381
--AaB03x
content-disposition: form-data; name="campo1"
1234
--AaB03x
content-disposition: form-data; name="campo2"
Miguel
--AaB03x
content-disposition: form-data; name="arquivo1"; filename="minha-foto.jpg"
Content-Type: image/jpeg
Content-Transfer-Encoding: binary
ÿØÿà�JFIF��`�`��ÿî�Adobe�d����ÿá]Exif��MM�*����2�������b;�������vGF�������GI�����?������
--AaB03x--
Some rules for content formation:
Header Content-type
: must be multipart/form-data; boundary=$divisor-aleatorio
replacing the random splitter with something really random and with almost 0 chance of repeating itself in the contents of the binary file or in any field sent.
Header Content-Length
: must have the size of the request, counting from the first divisor (in the previous example is--AaB03x
), to the last character of the terminator (``-Aab03x--)
For each field or file:
- add the splitter
- add division headers:
content-disposition: form-data
name="nome-do-campo-no-html"
- if it’s file:
filename="nome-do-arquivo-sendo-enviado"
: only if it is file
Content-Type: image/jpeg
: mime type of file
Content-Transfer-Encoding: binary
- skip a line, and then send the data
- as soon as it is over there comes another splitter from the next field or the terminator
- add terminator
Submitting form
with multipart/form-data
In HTML, to indicate that you want to use encoding multipart/form-data
, just include in the tag form
the attribute enctype="multipart/form-data"
Tag documentation form
on MDN
According to MDN documentation, this is necessary when using a input
with type="file"
.
Could put the full line where the strange characters appear?
– stderr
@Qmechanic73, Bah, it’s really big.. I’m going to put a little bit more, I believe that the characters themselves don’t matter to us, I think it’s image code, which in the end results in it all, but I can’t confirm any of this..
– Ale
That’s the Base64 of the picture, probably.
– Felipe Avelar
I don’t think @Felipeavelar, see: http://pt.wikipedia.org/wiki/Base64, according to this definition I saw of course..
– Ale
@Alexandrec.Caus, it is very common in web technologies to transmit files and data according to this coding, I am not saying that this is the case, but it seems very... An example of how to convert an image to Base64
– Felipe Avelar
I think I figured it out, I used the
file_get_contents()
that I noticed on the link you sent me, and the code it generates is the same as the POST on facebook (the weird part), ie, the image was not encoded, that whole code there is the content of the image, now remains the doubt is, how I get all this code on the other page and interpret it to turn an image?– Ale