【问题标题】:how to create an html form to send http message with multipart/mixed mime type如何创建一个 html 表单以发送具有多部分/混合 mime 类型的 http 消息
【发布时间】:2013-06-03 07:12:13
【问题描述】:

我正在创建一个可处理来自用户的多个文件的宁静 Web 服务。从谷歌看来,正确的 mime 类型应该是多部分/混合的,所以我的 java web 服务代码(基于 Jersey)类似于:

@POST
@Consumes(MultiPartMediaTypes.MULTIPART_MIXED)
@Produces({
    MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON
})
@Path("/{Id}")
public CourseBean updateCourse(@PathParam("Id") final String id, final MultiPart multipart)
    throws WebServiceException
{
    //operations on multipart
    String this.id = id;
    return null;
}

在浏览器中,我运行下面的 html 来尝试将文件上传到 Web 服务:

<h1></h1>

<p>files</p>
<FORM action="http://localhost:8080/rest/1"
       enctype="multipart/mixed"
       method="POST">
<p>
   name:<INPUT type="text" name="submit-name"><BR>
   file <INPUT type="file" name="file"><BR>
   attachment <INPUT type="file" name="attachment"><BR>
   <INPUT type="submit" value="Send"> <INPUT type="reset">
 </FORM>

</body>
</html>

请注意这里的编码类型是“multipart/mixed”。但是,在我选择文件并单击发送按钮后,我的 Web 服务获取的 http 请求的 mime 类型更改为 application/x-www-form-urlencoded,这会导致“不支持的媒体类型" Web 服务端出错。

但是如果我把html中的enctype改成multipart/form-data,接收到的请求的mime类型是一样的:multipart/form-data。

所以我的问题是,我怎样才能创建一个 html 表单,它可以发送具有 mime 类型“multipart/mixed”的 http 消息?使用这个 html,我可以测试我的网络服务。

非常感谢。

【问题讨论】:

    标签: html web-services jersey mime-types multipartform-data


    【解决方案1】:

    HTML 表单总是使用 multipart/form-data 作为编码。这是一种在一个流中发送多个数据块的方法。每个块都有自己的标题(这是“多部分”功能)。网页总是会为表单中的每个“成功”元素发送一个这样的块,这意味着实际上所有元素都有内容,以及被点击的提交按钮。

    根据定义的RFC1867,可以通过两种方式发送文件:发送单个文件时,它本身就是流中的一部分。当发送多个文件时,它们被打包为 multipart/form-data 中的 multipart/mixed 块:POST 请求仍然具有 multipart/form-data 类型,但其中一个部分的类型为 multipart/mixed .

    请注意,仅当从单个输入元素发送多个文件时才会发生这种情况。如果有多个输入元素,它们将作为各自的块发送,并且不会创建嵌套的多部分流。

    该 RFC 是在 1995 年编写的,因此您希望 HTML 能够发送多个文件。这花了很长时间,但它已作为 HTML5 的一部分添加到the multiple attribute。

    但是,当前的浏览器实现不使用 RFC 中描述的方法。相反,他们将发送多个具有相同名称的字段。换句话说,浏览器永远不会生成多部分/混合字段。

    【讨论】:

    • 这不是真的;正文标题 Content-Disposition 中的“名称”键值对所有这些文件都是相同的;但它不会发送多部分/混合。
    • @Henrik 我没有检查这个,只是假设他们会遵循 RFC。我现在已经更新了答案。感谢您的通知。
    • 我也是,直到我写了一个 http 客户端 ;)
    • 我写了一个服务器,但我还没有进入 multipart/mixed。这为我节省了一些工作。 :-)
    【解决方案2】:

    这是带有多文件浏览控件的请求的样子:

    Sample-form.html:

      <form action="http://localhost:1234" method="post" enctype="multipart/form-data">
        <p><input type="text" name="message" value="Hello World">
        <p><input type="file" name="images" multiple>
        <p><button type="submit">Submit</button>
      </form>
    

    这是服务器从 Safari 获取的内容:

    POST / HTTP/1.1
    

    主持人:

    POST / HTTP/1.1
    Host: localhost:1234
    Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryN8Y1MQiNiQs7fEEd
    Origin: file://
    Connection: keep-alive
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.4.10 (KHTML, like Gecko) Version/7.1.4 Safari/537.85.13
    Content-Length: 527
    Accept-Language: en-us
    Accept-Encoding: gzip, deflate
    
    ------WebKitFormBoundaryN8Y1MQiNiQs7fEEd
    Content-Disposition: form-data; name="message"
    
    Hello World
    ------WebKitFormBoundaryN8Y1MQiNiQs7fEEd
    Content-Disposition: form-data; name="images"; filename="testfile1.txt"
    Content-Type: text/plain
    
    Hello World, no trailling newlines
    ------WebKitFormBoundaryN8Y1MQiNiQs7fEEd
    Content-Disposition: form-data; name="images"; filename="testfile2.txt"
    Content-Type: text/plain
    
    Hello world, with TWO newlines at the end (NOT CRLF)
    
    
    ------WebKitFormBoundaryN8Y1MQiNiQs7fEEd--
    

    来自火狐:

    POST / HTTP/1.1
    Host: localhost:1234
    User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:37.0) Gecko/20100101 Firefox/37.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: en-US,en;q=0.5
    Accept-Encoding: gzip, deflate
    Connection: keep-alive
    Content-Type: multipart/form-data; boundary=---------------------------16701619336528579941090352635
    Content-Length: 599
    
    -----------------------------16701619336528579941090352635
    Content-Disposition: form-data; name="message"
    
    Hello World
    -----------------------------16701619336528579941090352635
    Content-Disposition: form-data; name="images"; filename="testfile1.txt"
    Content-Type: text/plain
    
    Hello World, no trailling newlines
    -----------------------------16701619336528579941090352635
    Content-Disposition: form-data; name="images"; filename="testfile2.txt"
    Content-Type: text/plain
    
    Hello world, with TWO newlines at the end (NOT CRLF)
    
    
    -----------------------------16701619336528579941090352635--
    

    【讨论】:

      【解决方案3】:

      HTML 表单不支持以multipart/mixed 发送数据。它们最接近,您可能想要使用的是multipart/form-data。如果您的 REST 网络服务只能接受 multipart/mixed,那么您将无法直接从 HTML 表单调用它。

      查看这个问题了解更多详情:What does enctype='multipart/form-data' mean?

      【讨论】:

      • 感谢您让我知道 html 表单不支持多部分/混合。提交表单时是否可以使用javascript将表单的mime类型更改为multipart/mixed?
      • 不,这是不可能的。 Web 浏览器不知道任何关于 multipart/mixed 的信息,因此无法以该格式提交表单数据。
      猜你喜欢
      • 2017-01-31
      • 2011-07-25
      • 2013-04-20
      • 2023-03-22
      • 2014-09-07
      • 2019-07-21
      • 2017-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多