详解 表单序列化
一、FormData 概述
-
FormData 是在 XMLHttpRequest 2级定义的
-
作用: 创建 后台需要的 表单格式的数据,便于 XHR传输
-
适用于: post请求表单序列化(支持上传文件的表单)
-
兼容: IE9-浏览器不支持
二、创建 FormData 实例
-
创建 FormData 对象,项目中提交表单代码
-
语法:
var formData = new FormData()
-
构造函数
FormData
可接受一个参数:form 表单这个DOM对象(约束:每一项表单必须要有 name 属性) -
举例:
-
<form id="myForm" action="" method="post">
<input type="text" name="name">名字
<input type="password" name="psw">密码
<input type="submit" value="提交">
</form>
// 获取页面已有的一个form表单
var form = document.getElementById("myForm");
// 用表单来初始化
var formData = new FormData(form);
$.ajax({
url: "server.php",
type: "POST",
data: formData,
processData: false, // 不处理数据
contentType: false // 不设置内容类型
});
- ajax 请求
processData
参数详解:-
默认值: true
-
默认情况下,通过data选项传递进来的数据,如果是一个对象(技术上讲只要不是字符串),都会处理转化成一个查询字符串,以配合默认内容类型 "application/x-www-form-urlencoded"
-
如果要发送 DOM 树信息或其它不希望转换的信息,请设置为 false。
-
三、FormData对象的 操作方法
获取数据:get( ) / getAll( )
- 语法:
-
formData.get(name)
: 获取 key 为 name 的第一个值 -
formData.getAll(name)
: 返回一个数组,获取 key 为 name 的所有值
-
添加数据:append( )
-
语法:
formData.append(key, value)
-
如果指定的key不存在则会新增一条数据,如果key存在,则添加到数据的末尾
formData.append("k1", "v1");
formData.append("k1", "v2");
formData.append("k1", "v1");
formData.get("k1"); // "v1"
formData.getAll("k1"); // ["v1","v2","v1"]
设置数据:set( )
-
语法:
formData.set(key, value)
-
如果指定的key不存在则会新增一条,如果存在,则会修改对应的value值
formData.append("k1", "v1");
formData.set("k1", "1");
formData.getAll("k1"); // ["1"]
判断存在:has( )
-
语法:
formData.has(key)
-
用来判断FormData 对象是否含有该 key;返回 布尔值
删除数据:delete( )
-
语法:
formData.delete(key)
-
删除指定 key 的值,如果有多个相同 key 值,会一并删除
遍历数据:keys( ) / values( ) / entries( )
-
三种方法,都返回一个迭代器
-
语法:
-
formData.keys( )
:返回的迭代器中 每一项为 formData 对象的 key 值 -
formData.values( )
:返回的迭代器中 每一项为 formData 对象的 value 值 -
formData.entries( )
:返回的迭代器中 每一项为 formData 对象的 [key, value] 数组
-
四、原生 JS 封装 表单序列化方法
function serialize(form) {
var parts = [],
elems = form.elements,
i = 0,
len = elems.length,
filed = null;
for (; i < len; i++) {
filed = elems[i];
switch (filed.type) {
case "select-one":
case "select-multiple":
if (filed.name.length) {
var j = 0,
opt,
optLen = filed.options.length;
for (; j < optLen; j++) {
opt = filed.options[j];
if (opt.selected) {
parts.push(encodeURIComponent(filed.name) + "=" + encodeURIComponent(opt.value));
}
}
}
break;
case undefined:
case "submit":
case "reset":
case "file":
case "button":
break;
case "radio":
case "checkbox":
if (!filed.checked) {
break;
}
default:
if (filed.name.length && filed.value) {
parts.push(encodeURIComponent(filed.name) + "=" + encodeURIComponent(filed.value));
}
}
}
return parts.join("&");
}
五、jQuery 中的表单序列化
将表单 序列化成 queryString 字符串:serialize( )
- 适用于: get 请求 的表单序列化
将表单 序列化成 对象数组:serializeArray( )
- 适用于: post 请求 的表单序列化
细节约束
-
以上两种 jQuery 的表单序列化方法,表单都需要有 name 属性
-
以上两种方式:只能传递一般的参数,上传文件的文件流是无法被序列化并传递的
示例如下
<body>
<form>
<input type="checkbox" name="fruit" value="apple" /> apple
<input type="checkbox" name="fruit" value="orange" checked="checked" /> orange
<input type="radio" name="sex" value="male" checked="checked" /> male
<input type="radio" name="sex" value="female" /> female
</form>
<button id="btn">submit</button>
</body>
<script>
document.getElementById('btn').addEventListener('click', () => {
console.log($("form").serialize()); // fruit=orange&sex=male
console.log(JSON.stringify($("form").serializeArray()));
// [{"name":"fruit","value":"orange"},{"name":"sex","value":"male"}]
})
</script>