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),只不过其取值不克为此除了上面提到的老三单,否则会变换成默认的编码。

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

相关文章