多部分HTTP响应

时间:2017-11-02 03:52:09

标签: javascript node.js server multipart hapijs

目标是让Node.js / hapi API服务器通过两件事来响应浏览器的AJAX请求:

  • 媒体文件(例如图像)
  • 包含有关文件
  • 的元数据的JSON对象

这是两个单独的项目,因为二进制数据不能轻易地存储在JSON中。否则,这将是一个单一资源。然而,最好是在一次回复中发送它们。

我们在multipart/form-data的单个请求中上传这些内容。在这种情况下,浏览器提供了一个内置机制来序列化正文,大多数服务器端框架都知道如何解析它。 但是,如何在相反的方向对响应做同样的事情呢?即,服务器如何序列化主体以将其传输到客户端?

据我所知,multipart/mixed可能是一种有用的内容类型。但很少有人谈论这个问题。大多数人似乎都倾向于提供两条独立的GET路线,每条路线一条。我不喜欢这样做,因为它可以让你了解竞争条件等等。我错过了什么?

另见hapijs/discuss#563中的问题。

2 个答案:

答案 0 :(得分:4)

您可以将回复作为multipart/form-data投放,并使用Response.formData()阅读客户回复

fetch("/path/to/server", {method:"POST", body:formData})
.then(response => response.formData())
.then(fd => {
  for (let [key, prop] of fd) {
    console.log(key, prop)
  }
})

let fd = new FormData();
fd.append("json", JSON.stringify({
  file: "image"
}));
fetch("data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH+GkNyZWF0ZWQgd2l0aCBhamF4bG9hZC5pbmZvACH5BAAKAAAAIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQACgABACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkEAAoAAgAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkEAAoAAwAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkEAAoABAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQACgAFACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQACgAGACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAAKAAcALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==")
  .then(response => response.blob())
  .then(blob => {
    fd.append("file", blob);
    new Response(fd)
      .formData()
      .then(formData => {
        for (let [key, data] of formData) {
          console.log(key, data)
        }
      })
  })

答案 1 :(得分:2)

如果您要使用多部分格式,我不会认为在上传(POST / PUT)和检索(GET)期间使用完全相同的格式存在任何明显错误。

我认为在使用HTTP时,在两个方向上使用相同的线上格式绝对是一种优雅。

但是,如果你想在PUT / POST和JSON期间使用GET发送表单数据,那么我会开始质疑这是否是正确的做法。

如果客户只想显示图片,那么多部件会让客户感到恼火。您是否考虑过使用不同的端点;一个用于图像,一个用于它的元数据?你有什么理由想把它们组合成一个资源?

或者,您也可以尝试在图像中嵌入信息。例如,JPEG允许使用EXIF添加自定义数据。至少你保留了直接打开图像的能力。

但是,我最后会说multipart/mixed是合适的,如果你只是想嵌入一个图像+一个json对象,但请记住:

  1. 消费可能有点不方便
  2. 它也有点不寻常
  3. 我非常确定多部分编码会要求您以一些7位编码对图像进行编码,这本身会导致请求大小爆炸。