Reputation: 3838
I tried to search for solution (for 2 days now) bot nothing helps me.
Because of many reasons I was forced to write own library in JavaScript to build a multipart/dorm-data body.
I checked how other libraries (for node) works and I read the spec. Then I wrote the code (https://github.com/jarrodek/ChromeRestClient/blob/files/app/elements/payload-editor/multipart-form-data.js) which is quite simple because the spec is.
However, my test server do not recognise parameters in the request. Any parameters (text or files).
My library generates generating the following HTTP message:
([NL]
represents new line character which is \r\n
)
POST /post HTTP/1.1[NL]
HOST: localhost:8081[NL]
content-type: multipart/form-data; boundary=-------------805520824430161118507807[NL]
content-length: 17789[NL]
-------------805520824430161118507807[NL]
Content-Disposition: form-data; name="image"; filename="arc-icon.png"[NL]
Content-Type: image/png[NL]
[NL]
�PNG[NL]
[binary data for about ~17700 bytes)[NL]
[NL]
-------------805520824430161118507807--[NL]
This is snapshot what is actually passed to a socket. The library builds the HTTP message and converts it into the ArrayBuffer
which is an argument in socket send function.
Now, I know there's some issue with my code, I just can't find it. I tried to add new line after message part (as in the code above) or not (after image data I always adding new line). Maybe someone can see an issue with the message here and point it out because I have no more ideas how to fix it :)
Upvotes: 1
Views: 1264
Reputation: 3838
Finally found it. The issue was with the boundary. According to spec body parts are separated from each other with two dash (-
) signs and the boundary string defined in content type. This two dashes missing in my message.
So the correct version of the message body is:
POST /post HTTP/1.1[NL]
HOST: localhost:8081[NL]
content-type: multipart/form-data; boundary=-------------805520824430161118507807[NL]
content-length: 17789[NL]
---------------805520824430161118507807[NL]
Content-Disposition: form-data; name="image"; filename="arc-icon.png"[NL]
Content-Type: image/png[NL]
[NL]
�PNG[NL]
[binary data for about ~17700 bytes)[NL]
[NL]
---------------805520824430161118507807--[NL]
Upvotes: 1
Reputation: 1
Not sure how I can get HTTP body message from FormData :) I can only do it using Fetch API and the request object.
You can iterate FormData
object, call .blob()
, first, then pass Blob
to new Response()
with .arrayBuffer()
chained.
<input name="files" type="file" accepts="image/*" multiple="multiple">
<script>
document.querySelector("input[type=file]")
.onchange = (e) => {
const [files, fd, arr] = [e.target.files, new FormData(), Array()];
for (let file of files) {
console.log(file);
fd.append(`file-${[...fd.keys()].length}`, file, file.name);
}
for (let [prop] of fd) {
let request = new Request("/", {
method: "POST",
body: fd.get(prop)
});
arr.push(
request.blob()
.then(blob => new Response(blob).arrayBuffer())
)
}
Promise.all(arr)
.then(buffers => {
for (let ab of buffers) {
console.log(ab);
let img = new Image;
img.onload = () => {
document.body.appendChild(img)
}
let url = URL.createObjectURL(new Blob([ab]));
img.src = url;
}
})
}
</script>
To read "multipart/form-data"
use .text()
chained to Request()
then parse returned data using String
or RegExp
methods.
Upvotes: 0