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

简介

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:
    窗体数据以纯文本格局举行编码,其中不含任何控件或格式字符。

HTTP/1.1
协议
规定的 HTTP 请求方法有
OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE、CONNECT 那二种。其中 POST
一般用来向服务端提交数据,本文紧要啄磨 POST 提交数据的二种方法。

咱俩知晓,HTTP 协议是以
ASCII 码传输,建立在 TCP/IP 商谈之上的应用层规范。规范把 HTTP
请求分为八个部分:状态行、请求头、音信主体。类似于上边那样:

<method> <request-URL> <version>
<headers>

<entity-body>

合计确定 POST
提交的数据必须放在音讯主体(entity-body)中,但情商并从未确定数额必须利用什么编码方式。实际上,开发者完全可以团结主宰新闻主体的格式,只要最终发送的
HTTP 请求满足下边的格式就可以。

但是,数据发送出去,还要服务端解析成功才有意义。一般服务端语言如
php、python 等,以及它们的
framework,都放置了自行分析常见数据格式的效益。服务端常常是依据请求头(headers)中的
Content-Type
字段来获知请求中的信息主体是用何种措施编码,再对主体展开解析。所以说到
POST 提交数据方案,包含了 Content-Type 和音信主体编码形式两有的。

是如何决定了表单的编码?

深谙表单元素<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为此后端在取多少后,要拓展解码。请求类似于上面那样(非亲非故的请求头在本文中都省略掉了):

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8

title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3

第一,Content-Type 被指定为
application/x-www-form-urlencoded;其次,提交的数据按照key1=val1&key2=val2 的艺术开展编码,key 和 val 都开展了 URL
转码。大多数服务端语言都对那种艺术有很好的辅助。例如 PHP 中,$_POST[‘title’]
可以获取到 title 的值,$_POST[‘sub’] 可以拿走 sub
数组。

诸多时候,我们用 Ajax
提交数据时,也是选择那种办法。例如 JQuery
QWrap 的 Ajax,Content-Type
默许值都是「application/x-www-form-urlencoded;charset=utf-8」。

style=”font-family: Microsoft YaHei;”>注意:若表单中有文件,则只留文件名。

multipart/form-data

这又是一个常见的 POST
数据交到的措施。大家应用表单上传文件时,必须让 <form> 表单的
enctype 等于 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--

注意:

  • 一般的话,methodenctype是三个例外的互不影响的性能,但在传文书时,method务须要指定为POST,否则文件只剩余filename了;

  • 当没有传文书时,enctype会改回默许的application/x-www-form-urlencoded

本条例子稍微复杂点。首学子成了一个
boundary 用于私分差其余字段,为了幸免与本文内容重复,boundary
很长很复杂。然后 Content-Type 里指明了多少是以 multipart/form-data
来编码,本次请求的 boundary
是什么样内容。音讯主体里依照字段个数又分为多少个社团类似的一部分,每部分都是以
--boundary
开始,紧接着是内容叙述信息,然后是回车,最终是字段具体内容(文本或二进制)。若是传输的是文件,还要包涵文件名和文件类型新闻。音信主体最后以
--boundary-- 标示停止。关于 multipart/form-data 的详细定义,请前往
rfc1867 查看。

那种情势相似用来上传文件,各大服务端语言对它也拥有美妙的协助。

上边提到的那二种 POST
数据的法门,都是浏览器原生接济的,而且近期正规中原生 <form>
表单也只援助那二种形式(通过
<form> 元素的 enctype 属性指定,默许为
application/x-www-form-urlencoded。其实 enctype 还支持
text/plain,不过用得分外少)。

乘势越来越多的 Web
站点,更加是 WebApp,全部利用 Ajax
进行数量交互之后,大家完全可以定义新的多寡交到格局,给开发带动越来越多造福。

text/plain

安份守己键值对排列表单数据key1=value1\r\nkey2=value2,不开展转义。

style=”font-family: Microsoft YaHei;”>注意:若表单中有文件,则只留文件名。

application/json及其他MIME类型

application/json 那个Content-Type
作为响应头大家肯定不陌生。实际上,现在更为多的人把它看成请求头,用来报告服务端音讯主体是种类化后的
JSON 字符串。由于 JSON 规范的风靡,除了低版本 IE
之外的各大浏览器都原生援救 JSON.stringify,服务端语言也都有处理 JSON
的函数,使用 JSON 不会遇上怎么麻烦。

JSON
格式支持比键值对复杂得多的结构化数据,那点也很有用。记得自己几年前做一个项目时,要求提交的多少层次格外深,我就是把多少
JSON 种类化之后来交给的。可是当下我是把 JSON 字符串作为
val,依然位居键值对里,以 x-www-form-urlencoded 格局交给。

Google 的
AngularJS 中的 Ajax 作用,默认就是交由 JSON
字符串。例如下边那段代码:

var data = {'title':'test', 'sub' : [1,2,3]};
$http.post(url, data).success(function(result) {
    ...
});

说到底发送的哀告是:

POST http://www.example.com HTTP/1.1 
Content-Type: application/json;charset=utf-8

{"title":"test","sub":[1,2,3]}

那种方案,可以一本万利的交付复杂的结构化数据,越发符合
RESTful 的接口。各大抓包工具如 Chrome
自带的开发者工具、Firebug、Fiddler,都会以树形结构体现 JSON
数据,相当要好。但也有些服务端语言还一向不辅助那种方法,例如 php
就不可能通过 $_POST
对象从地点的伸手中收获内容。那时候,需求自己入手处理下:在请求头中
Content-Type 为 application/json 时,从 php://input
里得到原始输入流,再 json_decode 成对象。一些 php
框架已经起首那样做了。

当然 AngularJS
也得以配备为利用 x-www-form-urlencoded
方式交给数据。如有需要,可以参见这篇作品

 

除此以外,还亟需讲明表单数据编码类型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),只但是其取值不可能用除了上边提到的七个,否则会转换成默许的编码。

可参考地址:《四种普遍的 POST
提交数据方式》

相关文章