enctype ='multipart / form是什么?
enctype='multipart/form-data'
在HTML
表单中enctype='multipart/form-data'
含义是什么以及我们应该在什么时候使用它?
当您发出POST请求时,您必须以某种方式编码形成请求主体的数据。
HTML表单提供了三种编码方法。
application/x-www-form-urlencoded
(默认) multipart/form-data
text/plain
正在完成添加application/json
,但已经放弃了。
格式的细节对大多数开发人员来说并不重要。 重要的一点是:
在编写客户端代码时,您需要知道的仅仅是当表单包含任何<input type="file">
元素时使用multipart/form-data
。
在编写服务器端代码时: 使用预先写好的表单处理库 (例如,Perl的CGI->param
或由PHP的$_POST
superglobal公开的那个),它将为您处理差异。 不要试图解析服务器收到的原始输入。
切勿使用text/plain
。
如果您正在编写(或调试)库来解析或生成原始数据,那么您需要开始担心格式。 你可能也想知道它的利益。
application/x-www-form-urlencoded
或多或少与URL末尾的查询字符串相同。
multipart/form-data
明显更复杂,但它允许将整个文件包含在数据中。 结果的一个例子可以在HTML 4规范中找到。
text/plain
由HTML 5引入,仅用于调试 - 从规范:它们不能被计算机可靠地解释 - 我会争辩说其他文件与工具相结合(如大多数浏览器的开发人员工具中的Net标签)更好)。
我们应该什么时候使用它
Quentin的答案是正确的:如果表单包含文件上传,则使用multipart/form-data
否则使用application/x-www-form-urlencoded
,如果您省略enctype
,则默认为默认值。
我要去:
HTML5参考
enctype
有三种可能性:
x-www-urlencoded
multipart/form-data
(spec指向RFC7578) text-plain
。 这是“不可靠的电脑解释”,所以它不应该用于生产,我们不会进一步考虑。 如何生成示例
一旦你看到每种方法的例子,就会明白它们是如何工作的以及何时应该使用每一种方法。
您可以使用以下示例生成示例
nc -l
或ECHO服务器 将表单保存为最小的.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>
我们将默认文本值设置aω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 'axCFx89b' > binary
运行我们的小回声服务器:
while true; do printf '' | nc -l 8000 localhost; done
在浏览器中打开HTML,选择文件并点击提交并检查终端。
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=---------------------------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
来验证 nc -l localhost 8000 | hd
,它说,字节:
61 CF 89 62
被发送( 61
=='a'和62
=='b')。
因此很明显:
Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266
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类型?
应用程序/ 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
很显然,文件数据并未发送,只有基本名称。 所以这不能用于文件。
至于文本字段,我们看到像a
和b
这样a
通常的可打印字符以一个字节发送,而不可打印的0xCF
如0xCF
和0x89
分别占用3个字节 : %CF%89
!
对照
文件上传通常包含很多不可打印的字符(例如图像),而文本表单几乎从不做。
从我们看到的例子来看:
multipart/form-data
:将几个字节的边界开销添加到消息中,并且必须花费一些时间计算它,但将每个字节发送一个字节。
application/x-www-form-urlencoded
:每个字段( &
)具有单个字节边界,但为每个不可打印字符添加3x的线性开销因子。
因此,即使我们可以发送带有application/x-www-form-urlencoded
,我们也不想这样做,因为它效率太低。
但是对于在文本字段中找到的可打印字符,它无关紧要并且生成的开销较小,因此我们只是使用它。
enctype='multipart/form-data
是一种允许通过POST发送文件的编码类型。 很简单,没有这种编码,文件不能通过POST发送。
如果您想允许用户通过表单上传文件,则必须使用此enctype。
链接地址: http://www.djcxy.com/p/3777.html上一篇: What does enctype='multipart/form
下一篇: International characters in filename in mutipart formdata