enctype='multipart/form-data' 在 HTML 形式中的含义是什么?我们何时应该使用它?
enctype='multipart/form-data'
HTML
enctype( ENC ode TYPE )属性指定在将表单数据提交到服务器时应如何编码表单数据 .
multipart/form-data 是enctype属性的值之一,用于具有文件上载的表单元素 . multi-part 表示表单数据分为 multiple parts 并发送到服务器 .
metaphor part :HTML文档有 two parts :头部和正文 .
通常这是当你有一个POST表单,需要将文件上传作为数据...这将告诉服务器它将如何编码传输的数据,在这种情况下,它将不会被编码,因为它只会传输和上传文件到服务器,例如上传图像或pdf时
我们什么时候应该使用它
Quentin的答案是正确的:如果表单包含文件上载,则使用 multipart/form-data ,否则使用 application/x-www-form-urlencoded ,如果省略 enctype ,则默认为 enctype .
multipart/form-data
application/x-www-form-urlencoded
enctype
我要去:
添加更多HTML5参考
解释 why 他是一个表单提交示例
enctype 为three possibilities:
x-www-urlencoded
multipart/form-data(规格指向RFC7578)
text-plain . 这是"not reliably interpretable by computer",所以它永远不应该在 生产环境 中使用,我们不会进一步研究它 .
一旦你看到每个方法的一个例子,就会明白它们是如何工作的,以及何时应该使用每个方法 .
您可以使用以下方法生成示
nc -l 或ECHO服务器:HTTP test server accepting GET/POST requests
nc -l
用户代理,如浏览器或cURL
将表单保存为最小的 .html 文件:
.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 .
aωb
aωb
ω
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
运行我们的小型echo服务器:
while true; do printf '' | nc -l 8000 localhost; done
在浏览器上打开HTML,选择文件,然后单击“提交”并检查终端 .
nc 打印收到的请求 .
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 == 'a'和 62 == 'b') .
61
62
因此很明显:
Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266 将内容类型设置为 multipart/form-data ,并表示字段由给定的 boundary 字符串分隔 .
Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266
boundary
每个字段在其数据之前获得一些子 Headers : Content-Disposition: form-data; ,字段 name , filename ,后跟数据 .
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
log(N)
Content-Type
具体如何确定被问到:How is mime type of an uploaded file determined by browser?
现在将 enctype 更改为 application/x-www-form-urlencoded ,重新加载浏览器,然后重新提交 .
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 这样的常见可打印字符是在一个字节中发送的,而不可打印的字符如 0xCF 和 0x89 分别占用 3 bytes : %CF%89 !
a
b
0xCF
0x89
%CF%89
文件上传通常包含许多不可打印的字符(例如图像),而文本形式几乎从不这样做 .
从我们看到的例子中可以看到:
multipart/form-data :向消息添加几个字节的边界开销,并且必须花一些时间计算它,但是在一个字节中发送每个字节 .
application/x-www-form-urlencoded :每个字段有一个字节边界( & ),但为每个不可打印的字符添加了 3x 的线性开销因子 .
&
因此,即使我们可以使用 application/x-www-form-urlencoded 发送文件,我们也不会这样做,因为它效率很低 .
但是对于在文本字段中找到的可打印字符,它无关紧要并且产生的开销较少,因此我们只是使用它 .
当您发出POST请求时,您必须以某种方式对构成请求主体的数据进行编码 .
HTML表单提供三种编码方法 .
application/x-www-form-urlencoded (默认值)
text/plain
正在努力增加application/json,但这已被放弃 .
格式的细节对大多数开发人员来说无关紧要 . 重点是:
当您编写客户端代码时,您需要知道的只是 use multipart/form-data when your form includes any <input type="file"> elements .
在编写服务器端代码时: Use a prewritten form handling library (例如Perl的 CGI->param 或PHP的 $_POST 暴露的代码)超级全球)它将为您处理差异 . 不要费心去解析服务器收到的原始输入 .
CGI->param
$_POST
Never use text/plain.
如果您正在编写(或调试)用于解析或生成原始数据的库,那么您需要开始担心该格式 . 您可能还想了解它的利益 .
application/x-www-form-urlencoded 或多或少与URL末尾的查询字符串相同 .
multipart/form-data 要复杂得多,但它允许整个文件包含在数据中 . 可以在HTML 4 specification中找到结果的示例 .
text/plain 由HTML 5引入,仅适用于调试 - 来自the spec:它们无法被计算机可靠地解释 - 我认为其他工具(如大多数浏览器的开发工具中的Net选项卡)更好为了那个原因) .
enctype='multipart/form-data' 表示不会编码任何字符 . 这就是为什么在将文件上传到服务器时使用此类型的原因 .因此,当表单需要上载二进制数据(如文件内容)时,将使用 multipart/form-data
将method属性设置为POST,因为无法使用表单将文件内容放在URL参数中 .
将enctype的值设置为multipart / form-data,因为数据将被拆分为多个部分,每个文件一个,另外一个用于可以与它们一起发送的表单主体的文本 .
提交表单时,您试图说您的浏览器通过HTTP协议发送网络上正确包含在TCP / IP协议消息结构中的消息 . 发送数据时,您可以使用 POST 或 GET 方法使用HTTP协议发送数据 . POST 告诉您的浏览器构建HTTP消息并将所有内容放在消息正文中(一种非常有用的方式,更安全,更灵活) . GET 对数据表示和长度有一些限制 .
POST
GET
发送文件时,有必要告诉HTTP协议您发送的文件中包含多个特征和信息 . 通过这种方式,可以一致地将数据发送到接收器并让它以当前格式打开文件等等......这是HTTP协议的要求,如图所示here
您无法使用默认的 enctype 参数发送文件,因为您的接收器可能在阅读时遇到问题(考虑到文件是特定操作系统的某些数据的描述符,如果您以这种方式看到它,也许您会理解为什么它如此重要为文件指定不同的 enctype ) .
这种做法还可以确保某些安全算法可以处理您的消息 . 应用程序级路由器也使用此信息,以充当外部数据的良好防火墙 .
好吧,正如你所看到的,使用特定的 enctype 文件并不是一件愚蠢的事情 .
enctype属性指定在将表单数据提交到服务器时应如何编码表单数据 . 只有在method =“post”时才能使用enctype属性 . 没有字符被编码 . 使用具有文件上载控件的表单时,此值是必需的
来自W3Schools
enctype='multipart/form-data 是一种允许通过POST发送文件的编码类型 . 很简单,没有这种编码,文件无法通过POST发送 .
enctype='multipart/form-data
如果要允许用户通过表单上载文件,则必须使用此enctype .
9 回答
enctype( ENC ode TYPE )属性指定在将表单数据提交到服务器时应如何编码表单数据 .
multipart/form-data 是enctype属性的值之一,用于具有文件上载的表单元素 . multi-part 表示表单数据分为 multiple parts 并发送到服务器 .
metaphor part :HTML文档有 two parts :头部和正文 .
通常这是当你有一个POST表单,需要将文件上传作为数据...这将告诉服务器它将如何编码传输的数据,在这种情况下,它将不会被编码,因为它只会传输和上传文件到服务器,例如上传图像或pdf时
Quentin的答案是正确的:如果表单包含文件上载,则使用
multipart/form-data
,否则使用application/x-www-form-urlencoded
,如果省略enctype
,则默认为enctype
.我要去:
添加更多HTML5参考
解释 why 他是一个表单提交示例
HTML5参考
enctype
为three possibilities:x-www-urlencoded
multipart/form-data(规格指向RFC7578)
text-plain . 这是"not reliably interpretable by computer",所以它永远不应该在 生产环境 中使用,我们不会进一步研究它 .
如何生成示例
一旦你看到每个方法的一个例子,就会明白它们是如何工作的,以及何时应该使用每个方法 .
您可以使用以下方法生成示
nc -l
或ECHO服务器:HTTP test server accepting GET/POST requests用户代理,如浏览器或cURL
将表单保存为最小的
.html
文件:我们将默认文本值设置为
aωb
,这意味着aωb
,因为ω
是U+03C9
,它是UTF-8中的字节61 CF 89 62
.创建要上传的文件:
运行我们的小型echo服务器:
在浏览器上打开HTML,选择文件,然后单击“提交”并检查终端 .
nc
打印收到的请求 .测试:Ubuntu 14.04.3,
nc
BSD 1.105,Firefox 40 .multipart / form-data
Firefox发送:
对于二进制文件和文本字段,按字面意思发送字节
61 CF 89 62
(UTF-8中的aωb
) . 你可以用nc -l localhost 8000 | hd
来验证它,它表示字节:已发送(
61
== 'a'和62
== 'b') .因此很明显:
Content-Type: multipart/form-data; boundary=---------------------------9051914041544843365972754266
将内容类型设置为multipart/form-data
,并表示字段由给定的boundary
字符串分隔 .每个字段在其数据之前获得一些子 Headers :
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-sequencesContent-Type
由浏览器自动确定 .具体如何确定被问到:How is mime type of an uploaded file determined by browser?
application / x-www-form-urlencoded
现在将
enctype
更改为application/x-www-form-urlencoded
,重新加载浏览器,然后重新提交 .Firefox发送:
显然,文件数据没有发送,只有基本名称 . 所以这不能用于文件 .
至于文本字段,我们看到像
a
和b
这样的常见可打印字符是在一个字节中发送的,而不可打印的字符如0xCF
和0x89
分别占用 3 bytes :%CF%89
!比较
文件上传通常包含许多不可打印的字符(例如图像),而文本形式几乎从不这样做 .
从我们看到的例子中可以看到:
multipart/form-data
:向消息添加几个字节的边界开销,并且必须花一些时间计算它,但是在一个字节中发送每个字节 .application/x-www-form-urlencoded
:每个字段有一个字节边界(&
),但为每个不可打印的字符添加了 3x 的线性开销因子 .因此,即使我们可以使用
application/x-www-form-urlencoded
发送文件,我们也不会这样做,因为它效率很低 .但是对于在文本字段中找到的可打印字符,它无关紧要并且产生的开销较少,因此我们只是使用它 .
当您发出POST请求时,您必须以某种方式对构成请求主体的数据进行编码 .
HTML表单提供三种编码方法 .
application/x-www-form-urlencoded
(默认值)multipart/form-data
text/plain
正在努力增加application/json,但这已被放弃 .
格式的细节对大多数开发人员来说无关紧要 . 重点是:
当您编写客户端代码时,您需要知道的只是 use multipart/form-data when your form includes any <input type="file"> elements .
在编写服务器端代码时: Use a prewritten form handling library (例如Perl的
CGI->param
或PHP的$_POST
暴露的代码)超级全球)它将为您处理差异 . 不要费心去解析服务器收到的原始输入 .Never use text/plain.
如果您正在编写(或调试)用于解析或生成原始数据的库,那么您需要开始担心该格式 . 您可能还想了解它的利益 .
application/x-www-form-urlencoded
或多或少与URL末尾的查询字符串相同 .multipart/form-data
要复杂得多,但它允许整个文件包含在数据中 . 可以在HTML 4 specification中找到结果的示例 .text/plain
由HTML 5引入,仅适用于调试 - 来自the spec:它们无法被计算机可靠地解释 - 我认为其他工具(如大多数浏览器的开发工具中的Net选项卡)更好为了那个原因) .enctype='multipart/form-data'
表示不会编码任何字符 . 这就是为什么在将文件上传到服务器时使用此类型的原因 .因此,当表单需要上载二进制数据(如文件内容)时,将使用
multipart/form-data
将method属性设置为POST,因为无法使用表单将文件内容放在URL参数中 .
将enctype的值设置为multipart / form-data,因为数据将被拆分为多个部分,每个文件一个,另外一个用于可以与它们一起发送的表单主体的文本 .
提交表单时,您试图说您的浏览器通过HTTP协议发送网络上正确包含在TCP / IP协议消息结构中的消息 . 发送数据时,您可以使用
POST
或GET
方法使用HTTP协议发送数据 .POST
告诉您的浏览器构建HTTP消息并将所有内容放在消息正文中(一种非常有用的方式,更安全,更灵活) .GET
对数据表示和长度有一些限制 .说明你发送的内容
发送文件时,有必要告诉HTTP协议您发送的文件中包含多个特征和信息 . 通过这种方式,可以一致地将数据发送到接收器并让它以当前格式打开文件等等......这是HTTP协议的要求,如图所示here
您无法使用默认的
enctype
参数发送文件,因为您的接收器可能在阅读时遇到问题(考虑到文件是特定操作系统的某些数据的描述符,如果您以这种方式看到它,也许您会理解为什么它如此重要为文件指定不同的enctype
) .不要忘记安全
这种做法还可以确保某些安全算法可以处理您的消息 . 应用程序级路由器也使用此信息,以充当外部数据的良好防火墙 .
好吧,正如你所看到的,使用特定的
enctype
文件并不是一件愚蠢的事情 .来自W3Schools
enctype='multipart/form-data
是一种允许通过POST发送文件的编码类型 . 很简单,没有这种编码,文件无法通过POST发送 .如果要允许用户通过表单上载文件,则必须使用此enctype .