序列化表单数据
代码
2 {
3 var encode = encodeURIComponent,
4 currCon,
5 currTag,
6 currVal,
7 currType,
8 currName,
9 currOpts,
10 currOpt,
11 temp,
12 result = [],
13 els = form.elements,
14 iTypeReg = /^checkbox|radio$/i,
15 bTypeReg = /^button|reset|image$/i,
16 A = Array;
17
18 for( var l = els.length; l--; )
19 {
20 currCon = els[ l ];
21 currTag = currCon.tagName.toLowerCase();
22 currType = currCon.type;
23 currVal = currCon.value;
24 currName = currCon.name;
25
26 if( currTag == 'button' || //如果是button,忽略掉
27 ( iTypeReg.test( currType ) && currCon.checked === false ) || //如果是radio或checkbox,而且checked为false,忽略掉
28 ( bTypeReg.test( currType ) || //如果是type=button,type=reset,type=image的控件,忽略掉
29 ( currType == 'file' ) ) //如果是file域 ,忽略掉
30 ) continue;
31
32 if( currCon.multiple === true && currType == 'select-multiple' ) //如果是多选框,遍历options特殊处理
33 {
34 currOpts = currCon.options;
35 for( var m = currOpts.length; m--; )
36 ( currOpt = currOpts[m] ).selected &&
37 ( result.push( encode( currName ) + '=' + encode( currOpt.value ) ) );
38 continue;
39 }
40
41 //其余的只需要取value就好
42 result.push( encode( currName ) + '=' + encode( currVal ) );
43 }
44
45 //处理附加的数据
46 for( var item in attachParams )
47 {
48 if( ( temp = attachParams[ item ] ) instanceof A ) //数组使用多选框处理方式
49 for( l = temp.length; l-- ; ) result.push( encode( item ) + '=' + encode( temp[l] ) );
50 else result.push( encode( item ) + '=' + encode( temp ) ); //其余直接取key=value就好
51 }
52
53 //最后加上分隔符的&
54 return result.join('&');
55 }
使用方式:
2 {
3 username : 'wait',
4 password : '123456789',
5 keys : [ 1,2,3,4,5 ]
6 });
OK,函数基本上就是这个样子了,还有有些可以改进的地方,比如 attachParams 可以接受string类型的。
上面也说了,这个函数一般都用在AJAX提交数据上。显然这个需求很旺盛,于是Firefox在版本4内置了一个 FormData 对象.
它4这样子用滴:
2 formData.append("username", "Groucho");
3 formData.append("accountnum", 123456);
4 formData.append("afile", fileInputElement.files[0]);
5
6 xhr.open("POST", "http://foo.com/submitform.php");
7 xhr.send(formData);
不但可以无中生有,还可以直接从form对象导出FormData对象:
2 formData = formElement.getFormData();
3 formData.append("serialnumber", serialNumber++);
4 xhr.send(formData);
看起来真的很好用蛤,但是,比较恶心银的是它不会被转换成字符串,formData本身就是一个对象,也只能用在AJAX的send方法里。
FormData参考:
https://developer.mozilla.org/en/XMLHttpRequest/FormData
https://developer.mozilla.org/En/XMLHttpRequest/Using_XMLHttpRequest#Using_FormData_objects
2009/7/9 update:
今天对FormData做了一些更详细的测试,原来FromData并不是像我想象的那样, 它的存在主要是为了解决上传文件的问题,也就是说,
如果你的表单中有许多控件,包括文件域,这时候你想同时用AJAX提交这些混合内容, 就可以使用FormData了(可以用AJAX上传文件已经是一个惊喜了)。
FormData 要求表单必须使用 method="post" enctype="multipart/form-data" (GET是无效的,什么也不会被传递)
而且FormData传递的数据也完全跟表单正常post一模一样,类似如下:
-----------------------------29962268197975
Content-Disposition: form-data; name="input-text"
text-value
-----------------------------29962268197975
Content-Disposition: form-data; name="input-hidden"
hidden-value
-----------------------------29962268197975
Content-Disposition: form-data; name="input-password"
password
-----------------------------29962268197975
Content-Disposition: form-data; name="input-radio-group"
radio-group-4
看来是我高兴早了,FormData是没有办法完全代替FormDataSerialize函数的功能的。