EBA*_*BAG 1290 html multipartform-data http-headers
enctype='multipart/form-data'HTML表单中的含义是什么?我们何时应该使用它?
Que*_*tin 1453
当您发出POST请求时,您必须以某种方式对构成请求主体的数据进行编码.
HTML表单提供三种编码方法.
application/x-www-form-urlencoded (默认)multipart/form-datatext/plain正在进行添加工作application/json,但这已被放弃.
(使用除HTML表单提交之外的其他方式生成的HTTP请求,可以进行其他编码.)
格式的细节对大多数开发人员来说无关紧要.重点是:
text/plain.在编写客户端代码时:
multipart/form-data时,你的形式包括任何<input type="file">元素multipart/form-data或application/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规范中找到结果的示例.
text/plain由HTML 5引入,仅用于调试 - 来自规范:它们不能被计算机可靠地解释 - 我认为其他工具(如大多数浏览器的开发工具中的Net选项卡)更好为了那个原因).
Cir*_*四事件 404
什么时候应该使用它
Quentin的答案是正确的:multipart/form-data如果表单包含文件上载,则使用,application/x-www-form-urlencoded否则,如果省略则默认为默认值enctype.
我要去:
有三种可能的enctype:
application/x-www-form-urlencodedmultipart/form-data(规格指向RFC7578)text/plain.这是"计算机无法可靠地解释",所以它永远不应该用于生产,我们不会进一步研究它.一旦你看到每个方法的一个例子,就会明白它们是如何工作的,以及何时应该使用每个方法.
您可以使用以下方法生成示
nc -l或ECHO服务器:接受GET/POST请求的HTTP测试服务器将表单保存到最小.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ω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>
Run Code Online (Sandbox Code Playgroud)
我们将默认文本值设置为aωb,这意味着a?b因为?是UTF-8 U+03C9中的字节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
Run Code Online (Sandbox Code Playgroud)
运行我们的小型echo服务器:
while true; do printf '' | nc -l 8000 localhost; done
Run Code Online (Sandbox Code Playgroud)
在浏览器上打开HTML,选择文件,然后单击"提交"并检查终端.
nc 打印收到的请求.
测试:Ubuntu 14.04.3,ncBSD 1.105,Firefox 40.
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--
Run Code Online (Sandbox Code Playgroud)
对于二进制文件和文本字段,字面61 CF 89 62(a?b以UTF-8为单位)按字面发送.您可以验证,nc -l localhost 8000 | hd表示字节:
61 CF 89 62
Run Code Online (Sandbox Code Playgroud)
被发送(61=='a'和62=='b').
因此很明显:
Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266将内容类型设置为multipart/form-data并表示字段由给定boundary字符串分隔.
每场得到它的数据之前,一些子头:Content-Disposition: form-data;,外地name的filename,其次是数据.
服务器读取数据直到下一个边界字符串.浏览器必须选择不会出现在任何字段中的边界,因此这就是边界可能因请求而异的原因.
因为我们有唯一的边界,所以不需要对数据进行编码:二进制数据按原样发送.
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 由浏览器自动确定.
如何确定的问题是:如何通过浏览器确定上传文件的mime类型?
现在更改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
Run Code Online (Sandbox Code Playgroud)
显然,文件数据没有发送,只有基本名称.所以这不能用于文件.
至于文本字段中,我们可以看到,平时打印的字符像a和b一个字节被送往,而不可打印的像0xCF,并0x89讨论了3个字节的每个:%CF%89!
文件上传通常包含许多不可打印的字符(例如图像),而文本形式几乎从不这样做.
从我们看到的例子中可以看到:
multipart/form-data:向消息添加几个字节的边界开销,并且必须花一些时间计算它,但是在一个字节中发送每个字节.
application/x-www-form-urlencoded:每个字段(&)具有单字节边界,但为每个不可打印字符添加3倍的线性开销因子.
因此,即使我们可以发送文件application/x-www-form-urlencoded,我们也不愿意,因为它是如此低效.
但是对于在文本字段中找到的可打印字符,它无关紧要并且产生的开销较少,因此我们只使用它.
Mat*_*ury 85
enctype='multipart/form-data是一种允许通过POST发送文件的编码类型.很简单,没有这种编码,文件无法通过POST发送.
如果要允许用户通过表单上载文件,则必须使用此enctype.
And*_*dry 73
提交表单时,您告诉浏览器通过HTTP协议发送网络上的消息,该消息正确地包含在TCP/IP协议消息结构中.HTML页面有一种向服务器发送数据的方法:使用<form>s.
提交表单时,如果创建了HTTP请求并将其发送到服务器,则该消息将包含表单中的字段名称和用户填写的值.这种传输可以发生POST或GET HTTP方法.
属性enctype只有在使用POST方法时才有意义.指定后,它会指示浏览器通过以特定方式对其内容进行编码来发送表单.来自MDN  - 表格enctype:
当method属性的值为post时,enctype是用于将表单提交给服务器的MIME内容类型.
application/x-www-form-urlencoded:这是默认值.发送表单时,将收集所有名称和值,并对最终字符串执行URL编码.multipart/form-data:字符不编码.当表单具有文件上载控件时,这很重要.您希望发送文件二进制文件,这可确保不改变比特流.text/plain:空格被转换,但不再执行编码.提交表单时,可能会出现一些安全问题,如RFC 7578第7节:多部分表单数据中所述 - 安全注意事项:
所有表单处理软件都应该
灵敏地处理用户提供的表单数据,因为它通常包含机密或个人
识别信息.在Web浏览器中广泛使用表单"自动填充"功能; 这些可能用于欺骗用户
在完成其他
无害任务时不知不觉地发送机密信息.multipart/form-data不提供任何
检查完整性,确保机密性,避免用户
混淆或其他安全功能的功能; 这些问题必须
通过表格填写和表格数据解释应用程序来解决.接收表单并处理表单的应用程序必须小心,不要将数据提供回不打算发送的请求表单处理站点.
在解释Content-
Disposition头字段的文件名时,重要的是不要无意中覆盖
收件人文件空间中的文件.
如果您是开发人员,并且您的服务器将处理用户提交的表单(可能最终包含敏感信息),则会引起您的注意.
GP *_*ngh 33
enctype='multipart/form-data'意味着不会编码任何字符.这就是为什么在将文件上传到服务器时使用此类型的原因.
所以multipart/form-data当窗体需要二进制数据,如一个文件的内容被使用,要上传
Pre*_*raj 11
将method属性设置为POST,因为无法使用表单将文件内容放入URL参数中.
将enctype的值设置为multipart/form-data,因为数据将被拆分为多个部分,每个文件一个,另外一个用于可以与它们一起发送的表单主体的文本.