很早以前,当还没有前端这个概念的时候,我在写表单提交完全不去理会表单数据的编码,在action属性里写好目标URL,剩下的啊交给浏览器吧~但是现在,更多时候我们都采用Ajax方式提交数据,这种原始的方式仅仅被当成优雅降级的产物。

当我们用异步方式提交表单,就需要稍微关注一下表单数据的编码问题了。回想一下,在写回调函数时是不是有根据过请求的Content-Type写不同业务逻辑的经历,那这个Content-Type和表单的编码有什么联系吗?有没有在明明前端已经发数据给后端了,后端的小伙伴死活取不到数据的情况?这些纠结的问题背后的原因真是困扰了我好久,今天在篇文章里就要把它们掰扯清楚!

是什么决定了表单的编码?

熟悉表单元素<form>的小伙伴,对其中的属性enctype一定不会陌生,就是它规定了对表单提交给服务器时表单数据编码的内容类型(Content Type)。以下引用,摘自HTML 4.01规范的Form章节

enctype = content-type [CI]
This attribute specifies the content type used to submit the form to the server

content type?这不就是我们在回调函数里判断返回数据的类型,并且是在请求头中的那个玩意儿吗?!没错!就是它!根据HTML 4.01规范的基础数据类型的说明,这个content type指定了连接资源的属性,同时也是MIME 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编码类型的例子:

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--

注意:

  • 一般来说,methodenctype是两个不同的互不影响的属性,但在传文件时,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

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 typeMIME type的关系。下次再总结一下Ajax提交表单的类型吧。

表单提交时编码类型enctype详解的更多相关文章

  1. JS之表单提交时编码类型enctype详解

    简介 form的enctype属性为编码方式,常用有两种:application/x-www-form-urlencoded和multipart/form-data,默认为application/x- ...

  2. 10天学会phpWeChat——第八天:Form类,丰富表单提交的字段类型

    通过前面七讲的系列教程,我们完成了一个包含后台并自适应PC+h5移动端的文章管理模块. 在实际的生产环境中,文章投稿.商品上传等操作并不会简单局限于一个text和textarea组成的表单.在实际中, ...

  3. 如何实现织梦dedecms表单提交时发送邮箱功能【已解决】

    我们通过织梦系统制作网站时,很多客户需要有在线留言功能,这时就会用到自定义表单.但是很多用户觉得经常登陆后台查看留言信息太麻烦了,于是想能否在提交留言是直接把内容发送到指定邮箱.网站经过测试终于实现了 ...

  4. form表单提交时选择性传值到后台

    正常情况下form表单提交会把表单内的内容提交到后台,但是如果有些内容只是作为展示或者是标记而不想传到后台,我们采用如下方法: jsp页面如下,我们不想提交id为userIdMark和pwdMark的 ...

  5. jQuery判断 form表单提交时一些文本框的判断

    一: form表单提交时如果表单里有input标签为空那么不提交form表单. <head> <script type="text/javascript"> ...

  6. php form表单提交时,action url中参数无效的解决方法

    表单提交时get方式的一个错误 <form class="form-inline pull-right" method="get" action=&quo ...

  7. webform非表单提交时防xss攻击

     1.webform默认配置下,主动防御了针对表单提交的xss攻击,但这次发生时因为url导致的,所以webform的默认防御机制不起作用  webform下输出非表单提交获得的数据的时候,要加htm ...

  8. 使用 HttpClient 进行表单提交时,遇到的问题

    问题 在开发微信支付的小微商户进件接口时,需要通过表单来上传身份证图片等数据.在微信支付接口文档也说明了,需要使用 multipart/form-data 的方式发送请求..NET 提供了 Multi ...

  9. 防止表单提交时刷新页面-阻止form表单的默认提交行为

    最近在写 ajax 提交的时候遇到一个问题,在执行 ajax 提交之后,浏览器页面自动刷新了,主要是没有 由于form 表单的默认提交行为.一下是几种阻止 form 表单默认提交行为的方式. 1.使用 ...

随机推荐

  1. Goroutines和Channels(四)

    如果说goroutine是Go语言程序的并发体的话,那么channels则是它们之间的通信机制. 一个channel是一个通信机制,它可以让一个goroutine通过它给另一个goroutine发送值 ...

  2. python 将元组解析为多个参数

    #create a tuple tuplex = , , print(tuplex) n1, n2, n3 = tuplex #unpack a tuple in variables print(n1 ...

  3. 安装Zookeeper和kafka,安装完毕后,遇到的错误

    按照原文链接 http://www.cnblogs.com/swneng/p/10212460.html 在windows下进行安装 之后运行 D:\00H_Bigdata\kafka_2.11-2. ...

  4. MongoDB(课时13 where条件过滤)

    3.4.2.8 条件过滤 关系型数据库开发对于数据的筛选,想到的一定是where语句,MongoDB里面提供的是"$where". 范例:使用where进行数据的查询 db.stu ...

  5. The Front-End Checklist

    做个记录,摘自Front-End Performance Checklist HTML Minified HTML: The HTML code is minified, comments, whit ...

  6. C#通过Oracle.ManagedDataAccess无法访问Oralce

    问题描述:通过C#引用Oracle.ManagedDataAccess.dll访问Oracle,写了如下一段代码,在本机能正常访问,但是将编译后的exe放到服务器上面就无法访问了,一直提示登录失败.而 ...

  7. 用EL時(el-api.jar,el-ri.jar ),要設isELIgnored="false"

    用EL時(el-api.jar,el-ri.jar ),要設isELIgnored="false" 否则jstl标签不显示. 加上 <%@page isELIgnored="false ...

  8. Jersey 2.x 运行项目

    现在我们已经有可以可以运行的项目了,让我们队这个项目进行一些测试吧. 你需要运行下面的一些命令行: mvn clean test 这个命令将会对项目进行编译后运行单元测试. 你应该会看到和下面类似的输 ...

  9. Kali Linux on Android # 实测:小米2s离线安装Kali Linux

    小米2s 离线安装Kali Linux 2017年2月4日  by 小甘丶 前段时间也研究过一两天,没弄明白,今天突然来兴致了,说研究一下吧,结果一不小心,就弄明白了! 第一次研究,主要是没弄明白这个 ...

  10. python-day21--sys模块

    sys模块是与python解释器交互的一个接口 1.sys.argv           命令行参数List,第一个元素是程序本身路径     # 传参 应用场景:权限控制 2.sys.path    ...