在javascript

时间:2017-02-03 21:26:25

标签: javascript http multipartform-data

我试图搜索解决方案(现在为2天)没有任何帮助我。

由于很多原因,我被迫在JavaScript中编写自己的库来构建一个multipart / dorm-data体。

我检查了其他库(节点)是如何工作的,我读了规范。然后我编写了代码(https://github.com/jarrodek/ChromeRestClient/blob/files/app/elements/payload-editor/multipart-form-data.js),这很简单,因为规范是。

但是,我的测试服务器无法识别请求中的参数。任何参数(文本或文件)。

我的库生成以下HTTP消息:

[NL]表示换行符\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]

这是实际传递给套接字的快照。该库构建HTTP消息并将其转换为ArrayBuffer,这是套接字发送函数中的参数。

现在,我知道我的代码存在一些问题,我找不到它。我尝试在消息部分之后添加新行(如上面的代码中所示)或不添加(在图像数据之后我总是添加新行)。也许有人可以在这里看到这个消息的问题并指出它,因为我没有更多的想法如何解决它:)

2 个答案:

答案 0 :(得分:1)

终于找到了它。问题在于边界。根据规范,身体部分彼此分开,带有两个破折号(-)符号和内容类型中定义的边界字符串。我的消息中遗漏了这两个破折号。

所以消息正文的正确版本是:

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]

答案 1 :(得分:0)

  

我不知道如何从FormData获取HTTP正文消息:)我只能这样做   使用Fetch API和请求对象来完成。

您可以迭代FormData对象,先调用.blob(),然后将Blob传递给new Response(),并.arrayBuffer()链接。

<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>

要阅读"multipart/form-data"使用.text()链接到Request(),然后使用StringRegExp方法解析返回的数据。