多部分 HTTP 响应

问题描述 投票:0回答:3

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

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

这是两个单独的项目,只是因为二进制数据无法轻松存储在 JSON 中。否则,这将是单一资源。尽管如此,最好将它们以单个响应的形式发送。

我们通过

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

据我所知,

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

另请参阅我的问题 hapijs/discuss#563

javascript node.js server multipart hapi.js
3个回答
19
投票

您可以将响应作为

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


4
投票

如果您要采用多部分格式,我认为在上传 (POST/PUT) 和检索 (GET) 过程中使用完全相同的格式并没有本质上的错误。

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

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

如果客户只想显示图像,multipart 会让客户感到厌烦。您是否考虑过仅使用不同的端点?一个用于图像,一个用于元数据?您出于什么原因要将它们合并为一个资源?

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

但是,我最后会说,如果您只想嵌入图像+ json 对象,

multipart/mixed
是合适的,但请记住:

  1. 消费可能有点不方便
  2. 也有点不寻常
  3. 我相当确定多部分编码将要求您以某种 7 位编码对图像进行编码,这本质上会导致请求大小大幅增加。

0
投票

我知道这是一个老问题,但我碰巧在这里并想到了另一种选择。您可以返回媒体文件的 mime 类型,这样对此感兴趣的客户端就可以显示它。元数据可以添加为自定义响应标头(如果您愿意,可以使用 JSON 值),以便元数据感知客户端可以提取返回的确切图像的相关信息,而无需竞争条件或双重查找。

© www.soinside.com 2019 - 2024. All rights reserved.