简介
form的enctype属性为编码方式,常用有两种:application/x-www-form-urlencoded和multipart/form-data,默认为application/x-www-form-urlencoded。
当action为get时候,浏览器用x-www-form-urlencoded的编码方式把form数据转换成一个字串(name1=value1&name2=value2...),然后把这个字串append到url后面,用?分割,加载这个新的url。
当action为post时候,浏览器把form数据封装到http body中,然后发送到server。如果没有type=file的控件,用默认的application/x-www-form-urlencoded就可以了。 但是如果有type=file的话,就要用到multipart/form-data了。浏览器会把整个表单以控件为单位分割,并为每个部分加上Content-Disposition(form-data或者file),Content-Type(默认为text/plain),name(控件name)等信息,并加上分割符(boundary)。
根据查找的资料得到如下总结:
- application/x-www-form-urlencoded: 窗体数据被编码为名称/值对。这是标准的编码格式。
- multipart/form-data: 窗体数据被编码为一条消息,页上的每个控件对应消息中的一个部分。
- text/plain: 窗体数据以纯文本形式进行编码,其中不含任何控件或格式字符。
是什么决定了表单的编码?
熟悉表单元素<form>
的小伙伴,对其中的属性enctype
一定不会陌生,就是它规定了对表单提交给服务器时表单数据编码的内容类型(Content Type)。
表单编码类型
知道了表单编码由enctype
决定的,那么它究竟有多少可选的取值呢?是不是所有的MIME类型它都能用呢?
实际上,根据HTML5 规范中所叙述的,enctype
具有以下三种选项,其中最后一项text/plain
是相比4.01新增的。
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
application/x-www-form-urlencoded
这是默认的编码类型,使用该类型时,会将表单数据中非字母数字的字符转换成转义字符,如"%HH",然后组合成这种形式key1=value1&key2=value2
;所以后端在取数据后,要进行解码。
注意:若表单中有文件,则只留文件名。
multipart/form-data
该类型用于高效传输文件、非ASCII数据和二进制数据,将表单数据逐项地分成不同的部分,用指定的分割符分割每一部分。每一部分都拥有Content-Disposition
头部,指定了该表单项的键名和一些其他信息;并且每一部分都有可选的Content-Type
,不特殊指定就为text/plain
。下面给出一个采用multipart/form-data
编码类型的例子:
Request Headers:
Accept:application/json, text/plain, */* Accept-Encoding:gzip, deflate Accept-Language:zh-CN,zh;q=0.8 Connection:keep-alive Content-Length:13125 Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryaqWXpQYCfMbAHgPh Cookie:shiro.sesssion=1a6d4f4d-ab5f-4a1b-a5cd-fc71cf9633cb Host:192.168.199.223 Origin:http://192.168.199.223 Referer:http://192.168.199.223/ User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36
Request Payload:
------WebKitFormBoundaryaqWXpQYCfMbAHgPh Content-Disposition: form-data; name="fileEnterprise"; filename="a.jpg" Content-Type: image/jpeg ------WebKitFormBoundaryaqWXpQYCfMbAHgPh Content-Disposition: form-data; name="enterpriseName" 有限责任公司 ------WebKitFormBoundaryaqWXpQYCfMbAHgPh Content-Disposition: form-data; name="unifiedSocialCreditCode" 91530700781667237G ------WebKitFormBoundaryaqWXpQYCfMbAHgPh--
注意:
- 一般来说,
method
和enctype
是两个不同的互不影响的属性,但在传文件时,method
必须要指定为POST
,否则文件只剩下filename了; - 当没有传文件时,
enctype
会改回默认的application/x-www-form-urlencoded
。
text/plain
按照键值对排列表单数据key1=value1\r\nkey2=value2
,不进行转义。
注意:若表单中有文件,则只留文件名。
application/json及其他MIME类型
另外,还需要说明表单数据编码类型application/json
,已经被W3C遗弃(详见HTML JSON Form Submission),建议不要在<form enctype="...">
中使用了,即使用了如果浏览器不支持,也会替换成application/x-www-form-urlencoded
。
同理,其余的MIME类型,也不支持,均会替换成默认编码application/x-www-form-urlencoded
。
注:1.MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。
2.MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。
想要了解详细的Mime 类型列表,请参考《W3school:MIME 参考手册》
总结
所以,enctype
可以认为就是表单数据的content type(MIME type)
,只不过其取值不能用除了上面提到的三个,否则会转换成默认的编码。