假设我们有如下 HTML 表单结构:
<form id="target">
<select name="pets" id="pet-select">
<option value="">--Please choose an option--</option>
<option value="dog">Dog</option>
<option value="cat" selected>Cat</option>
<option value="hamster">Hamster</option>
<option value="parrot">Parrot</option>
<option value="spider">Spider</option>
<option value="goldfish">Goldfish</option>
</select>
<select name="friends" multiple>
<option value="D.O" selected>D.O</option>
<option value="O.O">O.O</option>
<option value="K.O" selected>K.O</option>
</select>
<input name="name" value="KAI" />
<input type="password" name="password" value="123456" />
<input type="hidden" name="age" value="66" />
<textarea name="description">I am Superman</textarea>
<input type="checkbox" name="hobby" checked value="sleep" />Sleep
<input type="checkbox" name="hobby" value="eat" />Eat
<input type="radio" name="sex" checked value="Female" />Female
<input type="radio" name="sex" value="Male" />Male
</form>
我们可以使用以下方法序列化表单数据:
const serializeForm = formEle => {
const object = {}
const formData = new FormData(formEle)
formData.forEach((value, key) => object[key] = value)
return object
}
它已经能获取到大部分值,但是如果您想要支持多选列表或其他具有多个值的表单元素,可以使用如下片段:
const serializeForm = (formEle) =>
Array.from(new FormData(formEle)).reduce(
(p, [k, v]) =>
Object.assign({}, p, {
[k]: p[k] ? (Array.isArray(p[k]) ? p[k] : [p[k]]).concat(v) : v
}),
{}
)
console.log(serializeForm(document.querySelector('#target')))
将表单数据序列化为查询字符串
以下方法序列化由其字段的 name
和 value
组成的表单数据:
const serialize = formEle => {
// 获取所有字段
const fields = [].slice.call(formEle.elements, 0)
return fields.map(ele => {
const name = ele.name
const type = ele.type
// 忽视:没有 name 的字段、禁用(disabled)字段、文件(file)类型、未选中
checkbox/radio
if (
!name ||
ele.disabled ||
type === 'file' ||
(/(checkbox|radio)/.test(type) && !ele.checked)
) {
return ''
}
// 多选
if (type === 'select-multiple') {
return [...ele.options].map(opt => {
return opt.selected
? `${encodeURIComponent(name)}=${encodeURIComponent(opt.value)}`
: ''
})
.filter(item => item)
.join('&')
}
return `${encodeURIComponent(name)}=${encodeURIComponent(ele.value)}`
})
.filter(item => item)
.join('&')
}
console.log(serialize(document.querySelector('#target')))