multipart/form-data (一种POST 数据提交的方式)

一、初识multipart/form-data

enctype属性:

enctype:规定了form表单在发送到服务器时候编码方式,它有如下的三个值。

  • application/x-www-form-urlencoded:默认的编码方式。但是在用文本的传输和MP3等大型文件的时候,使用这种编码就显得 效率低下。
  • multipart/form-data指定传输数据为二进制类型,比如图片、mp3、文件。
  • text/plain:纯文体的传输。空格转换为 “+” 加号,但不对特殊字符编码。

二、multipart/form-data请求请求体的格式

  multipart/form-data是基于post方法来传递数据的,并且其请求内容格式为Content-Type: multipart/form-data,用来指定请求内容的数据编码格式。另外,该格式会生成一个boundary字符串来分割请求头与请求体的,具体的是以一个boundary=${boundary}来进行分割,伪码如下:

...
Content-Type: multipart/form-data; boundary=${boundary} 

--${boundary}
...
...

--${boundary}--

  上面boundary=${boundary}之后就是请求体内容了,请求体内容各字段之间以--${boundary}来进行分割,以--${boundary}--来结束请求体内容。

例子:

POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"

title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

数据包说明

  首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary 开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary-- 标示结束。关于 multipart/form-data 的详细定义,可在 rfc1867 查看。

  这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。

具体传递过程

  由于是POST请求,参数一般是以key-value的json字符串传递,或者将参数放入map传递。我们可以看到很多name,这个name就是key,下面的数据就是value,我们可以提取所有的key及value组成一个json字符串或者map传递即可。

提取出的json字符串类似于下面字段所示(非以上数据包提取,源自:如何传递Request PayLoad(请求负载)中的数据):

{"view:id1:txtSearch":"","$$viewid":"!f9fpyhcv2t!","$$xspsubmitid":"view:_id1:_id2:pager1_Group_lnk_2","$$xspexecid":"view:_id1:_id2:parent","$$xspsubmitvalue":"","$$xspsubmitscroll":"0|0","view:_id1":"view:_id1"}

或者map形式

            Map<String,String> m = new HashMap<String,String>();
            m.put("view:id1:txtSearch", "");
            m.put("$$viewid", "!f9fpyhcv2t!");
            m.put("$$xspsubmitid", "view:_id1:_id2:pager1_Group_lnk_2");
            m.put("$$xspexecid", "view:_id1:_id2:parent");
            m.put("$$xspsubmitvalue", "");
            m.put("$$xspsubmitscroll", "0|0");
            m.put("view:_id1", "view:_id1");


三、文中相关名词:

  • boundary属性
    根据RFC 1867定义,我们需要选择一段数据作为“分割边界”( boundary属性),这个“边界数据”不能在内容其他地方出现,一般来说使用一段从概率上说“几乎不可能”的数据即可。 不同浏览器的实现不同,每次post浏览器都会生成一个随机的30-40位长度的随机字符串,浏览器一般不会遍历这次post的所有数据找到一个不可能出现在数据中的字符串,这样代价过大,一般都是随机生成。
    Rfc1867这样说明{A boundary is selected that does not occur in any of the data. (This selection is sometimes done probabilisticly.)}。

(待更新)

参考:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值