Creating multipart/form-data request in own library in javascript

狂风中的少年 提交于 2019-12-08 05:02:34

问题


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]
[binnary 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 :)


回答1:


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]
[binnary data for about ~17700 bytes)[NL]
[NL]
---------------805520824430161118507807--[NL]



回答2:


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.



来源:https://stackoverflow.com/questions/42033251/creating-multipart-form-data-request-in-own-library-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!