56

为什么<form enctype=multipart/form-data>将文件上传到网络服务器时需要?

4

2 回答 2

86

它与浏览器如何打包二进制和表单数据以通过 HTTP 传输有关。默认情况下只发送表单数据,但如果表单需要支持上传文件,那么二进制数据也必须附加并与表单数据分开。

Scott Hanselman在这里给出了一个很好的解释:

HTTP 以及文件上传如何通过 HTTP 工作

对我来说,了解事情发生的原因和方式总是更好。如果您说“只是因为”或“随便什么,您只需添加它,它就会起作用”,那么我认为这很可悲。出于某种原因,虽然许多人了解 FORM POST 以及通常如何将表单数据传递到服务器,但当传输文件时,许多人只是认为它很神奇。为什么我们必须在包含文件上传的表单上添加 enctype="multipart/form=data"?因为表单现在将分多个部分发布。

如果你有这样的表格:

<form action="/home/uploadfiles" method="post" enctype="multipart/form-data">
    <label for="file">Filename:</label>
    <input type="file" name="file" id="file" />
    <input type="submit" name="submit" value="Submit" />
</form>

生成的表单 POST 将如下所示(稍微简化):

POST /home/uploadfiles HTTP/1.1
Content-Type: multipart/form-data; boundary=---------------------------7d81b516112482 
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64)
Content-Length: 324

-----------------------------7d81b516112482 
Content-Disposition: form-data; name="file"; filename="\\SERVER\Users\Scott\test.txt"
Content-Type: text/plain

foo
-----------------------------7d81b516112482
Content-Disposition: form-data; name="submit"

Submit
-----------------------------7d81b516112482--

请注意有关此 POST 的一些事项。首先,注意 content-type 和 boundary="" 以及稍后如何使用边界,确切地说,是多个部分之间的边界。看看第一部分如何显示我上传了一个文本/纯文本类型的文件。您可以从中插值,如果它们都同时发布,您希望多个文件如何显示。

当然,看看如果它只是一个没有 enctype="multipart/form=data" 的基本表单 POST 会有多么不同:

POST /home/uploadfiles HTTP/1.1 
Content-Type: application/x-www-form-urlencoded
UA-CPU: x86
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64)
Content-Length: 13

submit=Submit

看看内容类型有何不同?这是一个常规的、典型的 POST 形式。也许是非典型的,因为它只包含一个提交按钮!……

顺便说一句,如果您查看带有多个附件的电子邮件,它看起来与第一条 HTTP 消息的正文非常相似,因为多部分 MIME 编码随处可见,这在大多数好主意中都很常见。

于 2009-08-27T17:23:06.793 回答
4

这是RFC-1867中描述的 HTML 文件上传规范的一部分,这是允许以 HTML 形式上传文件的提议(大约 1995 年)。

从第 2 节开始:

该提案对 HTML 进行了两项更改:

1)为INPUT的TYPE属性添加FILE选项。
2) 允许 INPUT 标记的 ACCEPT 属性,这是输入允许的媒体类型或类型模式的列表。

此外,它定义了一种新的 MIME 媒体类型 multipart/form-data,并指定了 HTML 用户代理在解释
带有ENCTYPE="multipart/form-data"和/或<INPUT type="file">
标签的表单时的行为。

当您设置enctypemultipart/form-data时,浏览器使用“多部分边界”分隔上传中的每个文件或附件,这是定义每个“部分”开始和结束的唯一标识符。

这允许浏览器在一个请求中发送多个部分(因此得名),并使用自己的元数据(如 mime 类型、文件名等)识别每个部分。

于 2017-09-14T00:14:36.803 回答