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

enctype='multipart/form-data'在超文本标记语言中是什么意思,我们应该在什么时候使用它?

1583562 次浏览

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

超文本标记语言提供三种编码方法

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

正在进行添加#0的工作,但已被放弃。

(使用超文本标记语言表单提交以外的其他方式生成的HTTP请求也可以进行其他编码。JSON是用于Web服务的常见格式,有些仍然使用SOAP。)

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

  • 永远不要使用text/plain

当您编写客户端代码时:

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

当您编写服务器端代码时:

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

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

有时你会发现一个库不能处理这两种格式。Node.js最流行的处理表单数据的库是身体解析器,它不能处理多部分请求(但有留档建议一些替代方案)。


如果您正在编写(或调试)用于解析或生成原始数据的库,那么您需要开始担心格式。出于兴趣,您可能还想了解它。

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

multipart/form-data要复杂得多,但它允许将整个文件包含在数据中。结果的示例可以在超文本标记语言4规范中找到。

text/plain由超文本标记语言5引入,仅对调试有用-从该规范它们不能被计算机可靠地解释开始-我认为其他与工具(如大多数浏览器的开发人员工具中的的网络小组)相结合的工具更好)。

enctype='multipart/form-data是一种允许通过POST发送文件的编码类型。很简单,没有这种编码,文件就不能通过POST发送。

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

提交表单时,您告诉您的浏览器通过HTTP协议在网络上发送一条消息,正确地封装在TCP/IP协议消息结构中。超文本标记语言页面有一种向服务器发送数据的方法:使用<form>

当提交表单时,会创建一个HTTP请求并发送到服务器,消息将包含表单中的字段名称和用户填写的值。这种传输可能发生在POSTGEThttp方法中。

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

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

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

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

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

安全合规

提交表单时,可能会出现一些安全问题,如RFC 7578第7节:多部分表格数据-安全注意事项所述:

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

接收表单并处理它们的应用程序必须小心不向请求表单处理站点提供数据我不希望它被发送

解释Content-
的文件名时很重要配置头字段不会无意中覆盖
中的文件收件人的文件空间。

如果您是开发人员,您的服务器将处理用户提交的表单,这些表单最终可能包含敏感信息,这与您有关。

enctype='multipart/form-data'意味着没有字符将被编码。这就是为什么在将文件上传到服务器时使用这种类型。
因此,当表单需要上传二进制数据(例如文件的内容)时,使用multipart/form-data

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

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

我们应该什么时候使用它?

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

我要去:

  • 添加更多HTML5参考
  • 解释为什么他是对的,有一个表单提交示例

HTML5参考

enctype三种可能性

如何生成示例

一旦你看到每种方法的例子,它们是如何工作的,以及何时应该使用每种方法就变得很明显了。

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

将表单保存到最小的.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

运行我们的小回声服务器:

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

在浏览器上打开超文本标记语言,选择文件并单击提交并检查终端。

nc打印收到的请求。

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

多部分/表单数据

Firefox发送:

POST / HTTP/1.1[[ Less interesting headers ... ]]Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150Content-Length: 834
-----------------------------735323031399963166993862150Content-Disposition: form-data; name="text1"
text default-----------------------------735323031399963166993862150Content-Disposition: form-data; name="text2"
aωb-----------------------------735323031399963166993862150Content-Disposition: form-data; name="file1"; filename="a.txt"Content-Type: text/plain
Content of a.txt.
-----------------------------735323031399963166993862150Content-Disposition: form-data; name="file2"; filename="a.html"Content-Type: text/html
<!DOCTYPE html><title>Content of a.html.</title>
-----------------------------735323031399963166993862150Content-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=---------------------------735323031399963166993862150将内容类型设置为multipart/form-data,并表示字段由给定的boundary字符串分隔。

    但请注意:

    boundary=---------------------------735323031399963166993862150

    比实际屏障少两个破折号--

    -----------------------------735323031399963166993862150

    这是因为标准要求边界以两个破折号--开头。其他破折号似乎正是Firefox选择实现任意边界的方式。RFC 7578明确提到要求这两个前导破折号--是必需的:

    4.1. multipart/form-data的“边界”参数

    与其他多部分类型一样,部分用边界分隔符,使用CRLF构造,"--",以及“边界”参数。

  • 每个字段在其数据之前都有一些子标头:Content-Disposition: form-data;、字段namefilename,然后是数据。

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

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

    待办事项:最佳边界大小是多少(我打赌是0),以及找到它的算法的名称/运行时间?

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

    如何准确地确定被问到:浏览器如何确定上传文件的mime类型?

应用程序/x-www-表单-urlencode d

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

Firefox发送:

POST / HTTP/1.1[[ Less interesting headers ... ]]Content-Type: application/x-www-form-urlencodedContent-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发送文件,我们也不想这样做,因为它效率低下。

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

  • enctype(ENCodeTYPE)属性指定表单数据在提交给服务器时应如何编码。
  • 多部分/表单数据是enctype属性的值之一,用于具有文件上传的表单元素。多部分表示表单数据分成多个部分并发送到服务器。

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

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

enctype属性只能在方法="post"时使用。

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

W3学校

如果用户将通过表单上传文件,则此值是必需的

请读一下这个

https://www.w3schools.com/tags/att_form_enctype.asp