Html 为什么上传文件时需要form enctype=multipart/form-data?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1342506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 00:43:29  来源:igfitidea点击:

Why is form enctype=multipart/form-data required when uploading a file?

htmlhttpfile-uploadspecificationsrfc

提问by Nathan Taylor

Why is <form enctype=multipart/form-data>required when uploading a file to a web-server?

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

回答by Nathan Taylor

It has to do with how the browser packages binary and form data for transmission over HTTP. By default only form data is sent, but if the form needs to support uploading a file, then the binary data must also be appended and separated from the form data.

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

Scott Hanselman gives a good explanation of this here:

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

HTTP and How File Upload works via HTTP

It's always better, for me, to understand WHY and HOW something is happening. If you say "just because" or "whatever, you just add that, and it works" then I think that's sad. For some reason while many folks understand FORM POSTs and generally how form data is passed up to the server, when a file is transferred many just conclude it's magic. Why do we have to add enctype="multipart/form=data" on our forms that include file uploads? Because the form will now be POSTed in multiple parts.

If you have a form like this:

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>

The resulting Form POST will look like this (slightly simplified):

生成的表单 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--

Notice a few things about this POST. First, notice the content-type and boundary="" and how the boundary is used later, as exactly that, a boundary between the multiple parts. See how the first part shows that I uploaded a single file, of type text/plain. You can interpolate from this how you'd expect multiple files to show up if they were all POSTed at once.

And of course, look at how different this would look if it were just a basic form POST without the enctype="multipart/form=data" included:

请注意有关此 POST 的一些事项。首先,注意 content-type 和 bounding="" 以及以后如何使用边界,也就是多个部分之间的边界。看看第一部分如何显示我上传了一个文本/纯文本类型的文件。您可以从中插入您希望多个文件同时发布时显示的方式。

当然,看看如果它只是一个没有 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

See how the content type is different? This is a regular, typical form POST. Perhaps atypical in that it includes only a Submit button! ....

As an aside, if you looked at an email of yours with multiple attached files, it would look VERY similar to the body of the first HTTP message as multipart MIME encoding is found everywhere, as is common with most good ideas.

看看内容类型有什么不同?这是一个常规的、典型的表单 POST。也许不典型,因为它只包含一个提交按钮!....

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

回答by isapir

That is part of the specification for HTML File Upload as described in RFC-1867, which was the proposal to allow file uploads in HTML forms (circa 1995).

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

From section 2:

从第 2 节:

This proposal makes two changes to HTML:

1) Add a FILE option for the TYPE attribute of INPUT.
2) Allow an ACCEPT attribute for INPUT tag, which is a list of media types or type patterns allowed for the input.

In addition, it defines a new MIME media type, multipart/form-data, and specifies the behavior of HTML user agents when interpreting a
form with ENCTYPE="multipart/form-data"and/or <INPUT type="file">
tags.

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

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

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

When you set enctypeto multipart/form-data, the browser separates each file or attachment in the upload with a "multipart boundary", which is a unique identifier that defines the beginning and end of each "part".

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

That allows the browser to send multiple parts (hence the name) in one request, and identify each one with its own metadata like mime type, file name, etc.

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