很早之前,当尚未前端这个概念的时候,我在写表单提交彻底不去理会表单数据的编码,在action
属性里写好目标URL,剩下的啊交给浏览器吧~可是如今,更多时候咱们都采用Ajax方式提交数据,这种原始的方式仅仅被当成优雅降级的产物。html
当咱们用异步方式提交表单,就须要稍微关注一下表单数据的编码问题了。回想一下,在写回调函数时是否是有根据过请求的Content-Type
写不一样业务逻辑的经历,那这个Content-Type
和表单的编码有什么联系吗?有没有在明明前端已经发数据给后端了,后端的小伙伴死活取不到数据的状况?这些纠结的问题背后的缘由真是困扰了我很久,今天在篇文章里就要把它们掰扯清楚!前端
熟悉表单元素<form>
的小伙伴,对其中的属性enctype
必定不会陌生,就是它规定了对表单提交给服务器时表单数据编码的内容类型(Content Type)。如下引用,摘自HTML 4.01规范的Form章节:html5
enctype = content-type [CI]
This attribute specifies the content type used to submit the form to the serverjson
content type?这不就是咱们在回调函数里判断返回数据的类型,而且是在请求头中的那个玩意儿吗?!没错!就是它!根据HTML 4.01规范的基础数据类型的说明,这个content type指定了链接资源的属性,同时也是MIME type的那些媒体类型。后端
知道了表单编码由enctype
决定的,那么它究竟有多少可选的取值呢?是否是全部的MIME类型它都能用呢?
实际上,根据HTML5 规范中所叙述的,enctype
具备如下三种选项,其中最后一项text/plain
是相比4.01新增的。浏览器
application/x-www-form-urlencoded服务器
multipart/form-dataapp
text/plain异步
这是默认的编码类型,使用该类型时,会将表单数据中非字母数字的字符转换成转义字符,如"%HH",而后组合成这种形式key1=value1&key2=value2
;因此后端在取数据后,要进行解码。函数
注意:
若表单中有文件,则只留文件名;
该类型用于高效传输文件、非ASCII数据和二进制数据,将表单数据逐项地分红不一样的部分,用指定的分割符分割每一部分。每一部分都拥有Content-Disposition
头部,指定了该表单项的键名和一些其余信息;而且每一部分都有可选的Content-Type
,不特殊指定就为text/plain
。下面给出一个采用multipart/form-data
编码类型的例子:
Content-Type: multipart/form-data; boundary=AaB03x --AaB03x Content-Disposition: form-data; name="submit-name" Larry --AaB03x Content-Disposition: form-data; name="files"; filename="file1.txt" Content-Type: text/plain ... contents of file1.txt ... --AaB03x--
注意:
通常来讲,method
和enctype
是两个不一样的互不影响的属性,但在传文件时,method
必需要指定为POST
,不然文件只剩下filename了;
当没有传文件时,enctype
会改回默认的application/x-www-form-urlencoded
。
按照键值对排列表单数据key1=value1\r\nkey2=value2
,不进行转义。
注意:
若表单中有文件,则只留文件名;
另外,还须要说明表单数据编码类型application/json
,已经被W3C遗弃(详见HTML JSON Form Submission),建议不要在<form enctype="...">
中使用了,即便用了若是浏览器不支持,也会替换成application/x-www-form-urlencoded
。
同理,其他的MIME类型,也不支持,均会替换成默认编码application/x-www-form-urlencoded
。
PS:貌似如今浏览器都不支持了,我先用了下面几个浏览器:
FF43:Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:43.0) Gecko/20100101 Firefox/43.0
Chrome49, Safari9.1:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
IE6, 8
因此,enctype
能够认为就是表单数据的content type(MIME type)
,只不过其取值不能用除了上面提到的三个,不然会转换成默认的编码。
今天掰扯完了表单提交时的编码类型enctype
,以及它和content type
、MIME type
的关系。下次再总结一下Ajax提交表单的类型吧。