enctype ='multipart / form-data'是什么意思?

时间:2010-12-24 12:19:28

标签: html http-headers multipartform-data

enctype='multipart/form-data'在HTML表单中的含义以及我们何时应该使用它?

9 个答案:

答案 0 :(得分:1345)

当您发出POST请求时,您必须以某种方式对构成请求正文的数据进行编码。

HTML表单提供三种编码方法。

  • application/x-www-form-urlencoded(默认)
  • multipart/form-data
  • text/plain

正在努力添加application/json,但这已被放弃。

(使用除HTML表单提交之外的其他方式生成的HTTP请求,可以进行其他编码。)

格式的细节对大多数开发人员来说无关紧要。重点是:

  • 切勿使用text/plain

编写客户端代码时:

  • 当您的表单包含任何multipart/form-data元素
  • 时,请使用<input type="file">
  • 否则您可以使用multipart/form-dataapplication/x-www-form-urlencoded,但application/x-www-form-urlencoded会更有效率

编写服务器端代码时:

  • 使用预先编写的表单处理库

大多数(例如Perl的CGI->param或PHP的$_POST超全局公开的那个)将为您处理差异。不要试图解析服务器收到的原始输入。

有时你会发现一个无法处理这两种格式的库。 Node.js用于处理表单数据的最流行的库是body-parser,它不能处理多部分请求(但有文档推荐一些替代方案)。


如果您正在编写(或调试)用于解析或生成原始数据的库,那么您需要开始担心格式。你可能也想为了这个利益而知道它。

application/x-www-form-urlencoded或多或少与URL末尾的查询字符串相同。

multipart/form-data要复杂得多,但它允许整个文件包含在数据中。可以在HTML 4 specification中找到结果的示例。

text/plain由HTML 5引入,仅适用于调试 - 来自the spec它们无法通过计算机可靠地解释 - 我认为其他人与工具结合使用(如大多数浏览器的开发人员工具中的Net选项卡)对此更好。

答案 1 :(得分:375)

  

我们什么时候应该使用它

Quentin的回答是正确的:如果表单包含文件上传,则使用multipart/form-data,否则使用application/x-www-form-urlencoded,如果省略enctype,则默认为默认值。

我要去:

  • 添加更多HTML5参考
  • 使用表单提交示例解释为什么他是对的

HTML5参考

enctypethree possibilities

如何生成示例

一旦你看到每个方法的一个例子,就会明白它们是如何工作的,以及何时应该使用每个方法。

您可以使用以下方式生成示例:

将表单保存到最小.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <title>upload</title>
</head>
<body>
<form action="http://localhost:8000" method="post" enctype="multipart/form-data">
  <p><input type="text" name="text1" value="text default">
  <p><input type="text" name="text2" value="a&#x03C9;b">
  <p><input type="file" name="file1">
  <p><input type="file" name="file2">
  <p><input type="file" name="file3">
  <p><button type="submit">Submit</button>
</form>
</body>
</html>

我们将默认文本值设置为a&#x03C9;b,这意味着aωb因为ωU+03C9,这是UTF-8中的字节61 CF 89 62

创建要上传的文件:

echo 'Content of a.txt.' > a.txt

echo '<!DOCTYPE html><title>Content of a.html.</title>' > a.html

# Binary file containing 4 bytes: 'a', 1, 2 and 'b'.
printf 'a\xCF\x89b' > binary

运行我们的小型echo服务器:

while true; do printf '' | nc -l 8000 localhost; done

在浏览器上打开HTML,选择文件并单击“提交”并检查终端。

nc打印收到的请求。

测试:Ubuntu 14.04.3,nc BSD 1.105,Firefox 40。

的multipart / form-data的

Firefox发送:

POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
Content-Length: 834

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text1"

text default
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text2"

aωb
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain

Content of a.txt.

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file2"; filename="a.html"
Content-Type: text/html

<!DOCTYPE html><title>Content of a.html.</title>

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file3"; filename="binary"
Content-Type: application/octet-stream

aωb
-----------------------------735323031399963166993862150--

对于二进制文件和文本字段,字面上发送字节61 CF 89 62(UTF-8中的aωb)。您可以使用nc -l localhost 8000 | hd验证该字段,其中包含字节:

61 CF 89 62

已发送(61 =='a'和62 =='b')。

因此很明显:

  • Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266将内容类型设置为multipart/form-data,并说明字段由给定的boundary字符串分隔。

  • 每个字段在其数据之前获取一些子标题:Content-Disposition: form-data;,字段namefilename,后跟数据。

    服务器读取数据直到下一个边界字符串。浏览器必须选择一个不会出现在任何字段中的边界,因此这就是边界可能因请求而异的原因。

    因为我们有唯一的边界,所以不需要对数据进行编码:二进制数据按原样发送。

    TODO:什么是最佳边界大小(我打赌log(N)),以及找到它的算法的名称/运行时间?询问:https://cs.stackexchange.com/questions/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequences

  • Content-Type由浏览器自动确定。

    如何确定是在How is mime type of an uploaded file determined by browser?

  • 询问的

应用程序/ x-WWW窗体-urlencoded

现在将enctype更改为application/x-www-form-urlencoded,重新加载浏览器,然后重新提交。

Firefox发送:

POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: application/x-www-form-urlencoded
Content-Length: 51

text1=text+default&text2=a%CF%89b&file1=a.txt&file2=a.html&file3=binary

显然没有发送文件数据,只发送了基本名称。所以这不能用于文件。

对于文本字段,我们看到常见的可打印字符(如ab)以一个字节发送,而不可打印的字符(如0xCF0x89每个人占用 3个字节%CF%89

比较

文件上传通常包含大量不可打印的字符(例如图片),而文字形式几乎从不这样做。

从我们看到的例子中可以看出:

  • multipart/form-data:向消息添加几个字节的边界开销,并且必须花一些时间来计算它,但是用一个字节发送每个字节。

  • application/x-www-form-urlencoded:每个字段(&)都有一个字节边界,但会添加线性开销因子 3x 每个不可打印的角色。

因此,即使我们可以发送application/x-www-form-urlencoded的文件,我们也不会这样做,因为它效率很低。

但是对于在文本字段中找到的可打印字符,它无关紧要并且产生的开销较少,所以我们只是使用它。

答案 2 :(得分:83)

enctype='multipart/form-data是一种编码类型,允许通过 POST 发送文件。很简单,如果没有这种编码,则无法通过 POST 发送文件。

如果您想允许用户通过表单上传文件,您必须使用此 enctype

答案 3 :(得分:72)

提交表单时,您告诉浏览器通过HTTP协议发送网络上的消息,该消息正确地包含在TCP / IP协议消息结构中。 HTML页面有一种向服务器发送数据的方法:使用<form> s。

提交表单时,如果创建HTTP请求并将其发送到服务器,则该消息将包含表单中的字段名称和用户填写的值。使用POSTGET HTTP方法可以进行此传输。

  • POST告诉您的浏览器构建HTTP消息并将所有内容放在消息正文中(这是一种非常有用的处理方式,更安全,也更灵活)。
  • GET将在查询字符串中提交表单数据。它对数据表示和长度有一些限制。

说明如何将表单发送到服务器

属性enctype仅在使用POST方法时才有意义。指定后,它会指示浏览器通过以特定方式对其内容进行编码来发送表单。来自MDN - Form enctype

  

当method属性的值为post时,enctype为MIME   用于将表单提交到服务器的内容类型。

  • application/x-www-form-urlencoded:这是默认设置。发送表单后,将收集所有名称和值,并在最终字符串上执行URL Encoding
  • multipart/form-data:字符未编码。当表单具有文件上载控件时,这很重要。您希望发送文件二进制文件,这可确保不改变比特流。
  • text/plain:转换空格,但不再执行编码。

安全

提交表单时,可能会出现一些安全问题,如RFC 7578 Section 7: Multipart form data - Security considerations中所述:

  

所有表单处理软件都应该处理用户提供的表单数据
  敏感,因为它通常包含机密或个人身份   识别信息。广泛使用形式“自动填充”   Web浏览器中的功能;这些可能会被用来欺骗用户   在完成其他情况时不知不觉地发送机密信息   无害的任务。 multipart / form-data不提供任何功能
  检查完整性,确保机密性,避免用户   混淆或其他安全功能;那些担忧必须是   由表格填写和表格数据解释应用程序解决。

     

接收表单并处理它们的应用程序必须小心   不将数据提供回请求表单处理站点   不打算发送。

     

在解释内容的文件名时很重要   处置头字段不会无意中覆盖中的文件   收件人的文件空间。

如果您是开发人员,并且您的服务器将处理用户提交的表单,这些表单最终可能包含敏感信息,则会引起您的注意。

答案 4 :(得分:30)

enctype='multipart/form-data'表示不会编码任何字符。这就是为什么在将文件上传到服务器时使用此类型的原因 因此,当表单需要上传的二进制数据(如文件内容)时使用multipart/form-data

答案 5 :(得分:8)

将method属性设置为POST,因为无法使用表单将文件内容放入URL参数中。

将enctype的值设置为multipart / form-data,因为数据将被拆分为多个部分,每个文件一个,另外一个用于可以与它们一起发送的表单主体的文本。

答案 6 :(得分:0)

  • enctype( ENC ode TYPE )属性指定在将表单数据提交到服务器时应如何编码表单数据。
  • multipart / form-data 是enctype属性的值之一,用于具有文件上载的表单元素。 多部分表示表单数据分为多个部分并发送到服务器。

答案 7 :(得分:0)

通常这是当你有一个POST表单需要将文件上传作为数据时...这将告诉服务器它将如何编码传输的数据,在这种情况下它不会被编码,因为它只会将文件传输并上传到服务器,例如上传图片或pdf时

答案 8 :(得分:-1)

  

enctype属性指定将表单数据提交到服务器时应如何编码。

     

仅当method =“ post”时才能使用enctype属性。

     

没有字符被编码。当您使用具有文件上传控件的表单时,此值是必需的

来自W3Schools