AJax技术

深入理解ajax系列第四篇:FormData

字号+ 作者:H5之家 来源:H5之家 2017-03-21 16:05 我要评论( )

前面的话 现代Web应用中频繁使用的一项功能就是表单数据的序列化,XMLHttpRequest 2级为此定义了FormData类型。FormData为序列化表单以及创建与表单格式相同的数

> 编程开发 > AJAX相关 >

深入理解ajax系列第四篇:FormData 2017-03-14 14:33 出处:清屏网 人气: 

前面的话

现代Web应用中频繁使用的一项功能就是表单数据的序列化,XMLHttpRequest 2级为此定义了FormData类型。FormData为序列化表单以及创建与表单格式相同的数据提供了便利。本文将先介绍表单编码,然后过渡到表单序列化,最后引出FormData的核心概念

表单编码

当用户提交表单时,表单中的数据(每个表单元素的名字和值)编码到一个字符串中并随请求发送。默认情况下,HTML表单通过POST方法发送给服务器,而编码后的表单数据则用做请求主体

对表单数据使用的编码方案相对简单:对每个表单元素的名字和值执行普通的URL编码(使用十六进制转义码替换特殊字符),使用等号把编码后的名字和值分开,并使用"&"符号分开名/值对。一个简单表单的编码如下所示

find=pizza&zipcode=01234&radius=1km

表单数据编码格式有一个正式的MIME类型

application/x-www-form-urlencoded

当使用POST方法提交这种顺序的表单数据时,必须"Content-Type"请求头为这个值

[注意]这种类型的编码并不需要HTML表单,在Ajax应用中,希望发送给服务器的很可能是一个javascript对象

前面展示的数据变成javascript对象的表单编码形式可能是:

{find: "pizza", zipcode: 01234, radius: "1km"}

表单编码在Web上如此广泛使用,同时所有服务器端的编程语言都能得到良好的支持,所以非表单数据的表单编码通常也是容易实现的事情

下面代码展示了如何实现对象属性的表单编码

function encodeFormData(data){ pairs = []; ){ if (!data.hasOwnProperty(name)){ continue; //跳过继承属性 } if (typeof data[name] === "function"){ continue; //跳过方法 } var value = data[name].toString(); //把值转换成字符串 name = encodeURIComponent(name.replace("%20", "+")); //编码名字 value = encodeURIComponent(value.replace("%20", "+"));//编码值 pairs.push(name + "=" + value); // 存入名值对 } return pairs.join('&'); //返回使用'&'连接的名值对 } var data = {name:'小火柴',age:28,sender:'male'}; //name=&age=28&sender=male console.log(encodeFormData(data)); 表单序列化

随着Ajax的出现,表单序列化已经成为一种常见需求。在javascript中,可以利用表单字段的type属性,连同name和value属性一起实现对表单的序列化。在编写代码之前,有必须先搞清楚在表单提交期间,浏览器是怎样将数据发送给服务器的

1、对表单字段的名称和值进行URL编码,使用和号(&)分隔

2、不发送禁用的表单字段

3、只发送勾选的复选框和单选按钮

4、不发送type为"reset"和"button"的按钮

5、多选选择框中的每个选中的值単独一个条目

6、在单击提交按钮提交表单的情况下,也会发送提交按钮;否则,不发送提交按钮。也包括type为"image"的<input>元素

7、<select>元素的值,就是选中的<option>元素的value特性的值。如果<option>元素没有value特性,则是<option>元素的文本值

在表单序列化过程中,一般不包含任何按钮字段,因为结果字符串很可能是通过其他方式提交的。除此之外的其他上述规则都应该遵循

在下面表单序列化serialize()函数中,首先定义了一个名为parts的数组,用于保存将要创建的字符串的各个部分。然后,通过for循环迭代每个表单字段,并将其保存在field变量中。在获得了一个字段的引用之后,使用switch语句检测其type属性

序列化过程中最麻烦的就是<select>元素,它可能是单选框也可能是多选框。为此,需要遍历控件中的每一个选项,并在相应选项被选中的情况下向数组中添加一个值。对于单选框,只可能有一个选中项,而多选框则可能有零或多个选中项。这里的代码适用于这两种选择框,至于可选项的数量则是由浏览器控制的。在找到一个选中项之后,需要确定使用什么值。如果不存在value特性,或者虽然存在该特性,但值为空字符串,都要使用选项的文本来代替。为检査这个特性,在DOM兼容的浏览器中需要使用hasAttribute()方法,而在IE7-中需要使用特性的specified属性

如果表单中包含<fieldset>元素,则该元素会出现在元素集合中,但没有type属性。因此,如果type属性未定义,则不需要对其进行序列化。同样,对于各种按钮以及文件输入字段也是如此(文件输入字段在表单提交过程中包含文件的内容;但是,这个字段是无法模仿的,序列化时一般都要忽略)

对于单选按钮和复选框,要检查其checked属性是否被设置为false,如果是则退出switch语句。如果checked属性为true,则继续执行default语句,即将当前字段的名称和值进行编码,然后添加到parts数组中。函数的最后一步,就是使用join()格式化整个字符串,也就是用和号来分隔每一个表单字段

最后,serialize()函数会以査询字符串的格式输出序列化之后的字符串

function serialize(form){ var parts = [],field = null,option,optValue; for (var i=0, len=form.elements.length; i < len; i++){ field = form.elements[i]; switch(field.type){ : case "select-multiple": //如果该<select>控件设置为name属性 if (field.name.length){ for (var j=0,optLen = field.options.length; j < optLen; j++){ //选择<option>控件 option = field.options[j]; //如果该<option>控件被选中 if (option.selected){ optValue = ""; (option.hasAttribute){ optValue = (option.hasAttribute("value") ? option.value : option.text); } else { optValue = (option.attributes["value"].specified ? option.value : option.text); } //将键和值分别进行编码并用'='连接起来 parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(optValue)); } } } break; : : : : //custom button break; : (!field.checked){ break; } default: if (field.name.length){ parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value)); } } } return parts.join("&"); } ====>红>蓝=============> > <script> var oForm = document.forms.form; oForm.onchange = function(e){ e = e || event; result.innerHTML = serialize(form); } </script> FormData

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 关于web通信技术:反向ajax, polling, long polling, forever iframes, co

    关于web通信技术:反向ajax, polling, long polling, forever iframes

    2017-03-21 18:00

  • 【分享】学习前端从入门到进阶历程,愿将我一生奉献给代码!

    【分享】学习前端从入门到进阶历程,愿将我一生奉献给代码!

    2017-03-21 16:01

  • www.jqueryajax.com

    www.jqueryajax.com

    2017-03-21 11:00

  • 前端必备HTTP技能之Ajax技术详解

    前端必备HTTP技能之Ajax技术详解

    2017-03-20 18:02

网友点评