使用 form-serialize 一次拿到表单所有值

三葉Leaves Author

form-serialize 是一个用于将 HTML <form> 表单内容序列化成 JavaScript 对象或查询字符串的轻量级 JavaScript 库,常用于在前端处理表单数据,尤其适合配合 AJAX 提交。

CDN 可以在这里找到:form-serialize-js CDN by jsDelivr - A CDN for npm and GitHub

两种引入方式:

1
2
# npm 安装
npm install form-serialize

不知道为什么,虽然可以正常使用,但是下面这种方式会导致 nodejsmodule 报错,暂时想不到怎么解决,不过文末附带的源码是可以正常使用的。

1
<script src="https://cdn.jsdelivr.net/npm/form-serialize@0.7.2/index.min.js"></script>

使用方式:

1
2
3
4
5
6
7
import serialize from 'form-serialize';

const form = document.querySelector('form');
const data = serialize(form, { hash: true });

console.log(data);
// => { username: "alice", password: "123456" }

选项:
serialize(form, options)

  • form:HTMLFormElement
  • options
    • hash: true —— 输出为 JS 对象(默认是字符串)
    • empty: true —— 包括空字段
    • disabled: true —— 包括禁用字段

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
// get successful control from form and assemble into object  
// http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2

// types which indicate a submit action and are not successful controls
// these will be ignored
var k_r_submitter = /^(?:submit|button|image|reset|file)$/i;

// node names which could be successful controls
var k_r_success_contrls = /^(?:input|select|textarea|keygen)/i;

// Matches bracket notation.
var brackets = /(\[[^\[\]]*\])/g;

// serializes form fields
// @param form MUST be an HTMLForm element
// @param options is an optional argument to configure the serialization. Default output
// with no options specified is a url encoded string
// - hash: [true | false] Configure the output type. If true, the output will
// be a js object.
// - serializer: [function] Optional serializer function to override the default one.
// The function takes 3 arguments (result, key, value) and should return new result
// hash and url encoded str serializers are provided with this module
// - disabled: [true | false]. If true serialize disabled fields.
// - empty: [true | false]. If true serialize empty fields
function serialize(form, options) {
if (typeof options != 'object') {
options = { hash: !!options };
}
else if (options.hash === undefined) {
options.hash = true;
}

var result = (options.hash) ? {} : '';
var serializer = options.serializer || ((options.hash) ? hash_serializer : str_serialize);

var elements = form && form.elements ? form.elements : [];

//Object store each radio and set if it's empty or not
var radio_store = Object.create(null);

for (var i=0 ; i<elements.length ; ++i) {
var element = elements[i];

// ingore disabled fields
if ((!options.disabled && element.disabled) || !element.name) {
continue;
}
// ignore anyhting that is not considered a success field
if (!k_r_success_contrls.test(element.nodeName) ||
k_r_submitter.test(element.type)) {
continue;
}

var key = element.name;
var val = element.value;

// we can't just use element.value for checkboxes cause some browsers lie to us
// they say "on" for value when the box isn't checked if ((element.type === 'checkbox' || element.type === 'radio') && !element.checked) {
val = undefined;
}

// If we want empty elements
if (options.empty) {
// for checkbox
if (element.type === 'checkbox' && !element.checked) {
val = '';
}

// for radio
if (element.type === 'radio') {
if (!radio_store[element.name] && !element.checked) {
radio_store[element.name] = false;
}
else if (element.checked) {
radio_store[element.name] = true;
}
}

// if options empty is true, continue only if its radio
if (val == undefined && element.type == 'radio') {
continue;
}
}
else {
// value-less fields are ignored unless options.empty is true
if (!val) {
continue;
}
}

// multi select boxes
if (element.type === 'select-multiple') {
val = [];

var selectOptions = element.options;
var isSelectedOptions = false;
for (var j=0 ; j<selectOptions.length ; ++j) {
var option = selectOptions[j];
var allowedEmpty = options.empty && !option.value;
var hasValue = (option.value || allowedEmpty);
if (option.selected && hasValue) {
isSelectedOptions = true;

// If using a hash serializer be sure to add the
// correct notation for an array in the multi-select // context. Here the name attribute on the select element // might be missing the trailing bracket pair. Both names // "foo" and "foo[]" should be arrays. if (options.hash && key.slice(key.length - 2) !== '[]') {
result = serializer(result, key + '[]', option.value);
}
else {
result = serializer(result, key, option.value);
}
}
}

// Serialize if no selected options and options.empty is true
if (!isSelectedOptions && options.empty) {
result = serializer(result, key, '');
}

continue;
}

result = serializer(result, key, val);
}

// Check for all empty radio buttons and serialize them with key=""
if (options.empty) {
for (var key in radio_store) {
if (!radio_store[key]) {
result = serializer(result, key, '');
}
}
}

return result;
}

function parse_keys(string) {
var keys = [];
var prefix = /^([^\[\]]*)/;
var children = new RegExp(brackets);
var match = prefix.exec(string);

if (match[1]) {
keys.push(match[1]);
}

while ((match = children.exec(string)) !== null) {
keys.push(match[1]);
}

return keys;
}

function hash_assign(result, keys, value) {
if (keys.length === 0) {
result = value;
return result;
}

var key = keys.shift();
var between = key.match(/^\[(.+?)\]$/);

if (key === '[]') {
result = result || [];

if (Array.isArray(result)) {
result.push(hash_assign(null, keys, value));
}
else {
// This might be the result of bad name attributes like "[][foo]",
// in this case the original `result` object will already be // assigned to an object literal. Rather than coerce the object to // an array, or cause an exception the attribute "_values" is // assigned as an array. result._values = result._values || [];
result._values.push(hash_assign(null, keys, value));
}

return result;
}

// Key is an attribute name and can be assigned directly.
if (!between) {
result[key] = hash_assign(result[key], keys, value);
}
else {
var string = between[1];
// +var converts the variable into a number
// better than parseInt because it doesn't truncate away trailing // letters and actually fails if whole thing is not a number var index = +string;

// If the characters between the brackets is not a number it is an
// attribute name and can be assigned directly. if (isNaN(index)) {
result = result || {};
result[string] = hash_assign(result[string], keys, value);
}
else {
result = result || [];
result[index] = hash_assign(result[index], keys, value);
}
}

return result;
}

// Object/hash encoding serializer.
function hash_serializer(result, key, value) {
var matches = key.match(brackets);

// Has brackets? Use the recursive assignment function to walk the keys,
// construct any missing objects in the result tree and make the assignment // at the end of the chain. if (matches) {
var keys = parse_keys(key);
hash_assign(result, keys, value);
}
else {
// Non bracket notation can make assignments directly.
var existing = result[key];

// If the value has been assigned already (for instance when a radio and
// a checkbox have the same name attribute) convert the previous value // into an array before pushing into it. // // NOTE: If this requirement were removed all hash creation and // assignment could go through `hash_assign`. if (existing) {
if (!Array.isArray(existing)) {
result[key] = [ existing ];
}

result[key].push(value);
}
else {
result[key] = value;
}
}

return result;
}

// urlform encoding serializer
function str_serialize(result, key, value) {
// encode newlines as \r\n cause the html spec says so
value = value.replace(/(\r)?\n/g, '\r\n');
value = encodeURIComponent(value);

// spaces should be '+' rather than '%20'.
value = value.replace(/%20/g, '+');
return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + value;
}
  • 标题: 使用 form-serialize 一次拿到表单所有值
  • 作者: 三葉Leaves
  • 创建于 : 2025-06-15 00:00:00
  • 更新于 : 2025-07-10 13:40:50
  • 链接: https://blog.oksanye.com/d43684f6ab58/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
使用 form-serialize 一次拿到表单所有值