1- # 表单
1+ # 表单,FormData 对象
22
3- ## 概述
3+ ## 表单概述
44
55表单(` <form> ` )用来收集用户提交的数据,发送到服务器。比如,用户提交用户名和密码,让服务器验证,就要通过表单。表单提供多种控件,让开发者使用,具体的控件种类和用法请参考 HTML 语言的教程。本章主要介绍 JavaScript 与表单的交互。
66
@@ -44,6 +44,148 @@ user_name=张三&user_passwd=123&submit_button=提交
4444
4545注意,实际提交的时候,只要键值不是 URL 的合法字符(比如汉字“张三”和“确定”),浏览器会自动对其进行编码。
4646
47+ 点击` submit ` 控件,就可以提交表单。
48+
49+ ``` html
50+ <form >
51+ <input type =" submit" value =" 提交" >
52+ </form >
53+ ```
54+
55+ 上面表单就包含一个` submit ` 控件,点击这个控件,浏览器就会把表单数据向服务器提交。
56+
57+ 注意,表单里面的` <button> ` 元素如果没有用` type ` 属性指定类型,那么默认就是` submit ` 控件。
58+
59+ ``` html
60+ <form >
61+ <button >提交</button >
62+ </form >
63+ ```
64+
65+ 上面表单的` <button> ` 元素,点击以后也会提交表单。
66+
67+ 除了点击` submit ` 控件提交表单,还可以用表单元素的` submit() ` 方法,通过脚本提交表单。
68+
69+ ``` javascript
70+ formElement .submit ();
71+ ```
72+
73+ 表单元素的` reset() ` 方法可以重置所有控件的值(重置为默认值)。
74+
75+ ``` javascript
76+ formElement .reset ()
77+ ```
78+
79+ ## FormData 对象
80+
81+ ### 概述
82+
83+ 表单数据以键值对的形式向服务器发送,这个过程是浏览器自动完成的。但是有时候,我们希望通过脚本完成过程,构造和编辑表单键值对,然后通过` XMLHttpRequest.send() ` 方法发送。浏览器原生提供了 FormData 对象来完成这项工作。
84+
85+ FormData 首先是一个构造函数,用来生成实例。
86+
87+ ``` javascript
88+ var formdata = new FormData (form);
89+ ```
90+
91+ ` FormData() ` 构造函数的参数是一个表单元素,这个参数是可选的。如果省略参数,就表示一个空的表单,否则就会处理表单元素里面的键值对。
92+
93+ 下面是一个表单。
94+
95+ ``` html
96+ <form id =" myForm" name =" myForm" >
97+ <div >
98+ <label for =" username" >用户名:</label >
99+ <input type =" text" id =" username" name =" username" >
100+ </div >
101+ <div >
102+ <label for =" useracc" >账号:</label >
103+ <input type =" text" id =" useracc" name =" useracc" >
104+ </div >
105+ <div >
106+ <label for =" userfile" >上传文件:</label >
107+ <input type =" file" id =" userfile" name =" userfile" >
108+ </div >
109+ <input type =" submit" value =" Submit!" >
110+ </form >
111+ ```
112+
113+ 我们用 FormData 对象处理上面这个表单。
114+
115+ ``` javascript
116+ var myForm = document .getElementById (' myForm' );
117+ var formData = new FormData (myForm);
118+
119+ // 获取某个控件的值
120+ formData .get (' username' ) // ""
121+
122+ // 设置某个控件的值
123+ formData .set (' username' , ' 张三' );
124+
125+ formData .get (' username' ) // "张三"
126+ ```
127+
128+ ### 实例方法
129+
130+ FormData 提供以下实例方法。
131+
132+ - ` FormData.get(key) ` :获取指定键名对应的键值,参数为键名。如果有多个同名的键值对,则返回第一个键值对的键值。
133+ - ` FormData.getAll(key) ` :返回一个数组,表示指定键名对应的所有键值。如果有多个同名的键值对,数组会包含所有的键值。
134+ - ` FormData.set(key, value) ` :设置指定键名的键值,参数为键名。如果键名不存在,会添加这个键值对,否则会更新指定键名的键值。如果第二个参数是文件,还可以使用第三个参数,表示文件名。
135+ - ` FormData.delete(key) ` :删除一个键值对,参数为键名。
136+ - ` FormData.append(key, value) ` :添加一个键值对。如果键名重复,则会生成两个相同键名的键值对。如果第二个参数是文件,还可以使用第三个参数,表示文件名。
137+ - ` FormData.has(key) ` :返回一个布尔值,表示是否具有该键名的键值对。
138+ - ` FormData.keys() ` :返回一个遍历器对象,用于` for...of ` 循环遍历所有的键名。
139+ - ` FormData.values() ` :返回一个遍历器对象,用于` for...of ` 循环遍历所有的键值。
140+ - ` FormData.entries() ` :返回一个遍历器对象,用于` for...of ` 循环遍历所有的键值对。如果直接用` for...of ` 循环遍历 FormData 实例,默认就会调用这个方法。
141+
142+ 下面是` get() ` 、` getAll() ` 、` set() ` 、` append() ` 方法的例子。
143+
144+ ``` javascript
145+ var formData = new FormData ();
146+
147+ formData .set (' username' , ' 张三' );
148+ formData .append (' username' , ' 李四' );
149+ formData .get (' username' ) // "张三"
150+ formData .getAll (' username' ) // ["张三", "李四"]
151+
152+ formData .append (' userpic[]' , myFileInput .files [0 ], ' user1.jpg' );
153+ formData .append (' userpic[]' , myFileInput .files [1 ], ' user2.jpg' );
154+ ```
155+
156+ 下面是遍历器的例子。
157+
158+ ``` javascript
159+ var formData = new FormData ();
160+ formData .append (' key1' , ' value1' );
161+ formData .append (' key2' , ' value2' );
162+
163+ for (var key of formData .keys ()) {
164+ console .log (key);
165+ }
166+ // "key1"
167+ // "key2"
168+
169+ for (var value of formData .values ()) {
170+ console .log (value);
171+ }
172+ // "value1"
173+ // "value2"
174+
175+ for (var pair of formData .entries ()) {
176+ console .log (pair[0 ] + ' : ' + pair[1 ]);
177+ }
178+ // key1: value1
179+ // key2: value2
180+
181+ // 等同于遍历 formData.entries()
182+ for (var pair of formData) {
183+ console .log (pair[0 ] + ' : ' + pair[1 ]);
184+ }
185+ // key1: value1
186+ // key2: value2
187+ ```
188+
47189## 表单的内置验证
48190
49191### 自动校验
@@ -197,7 +339,7 @@ if (document.getElementById('myInput').validity.rangeOverflow) {
197339document .getElementById (' prompt' ).innerHTML = txt;
198340```
199341
200- ### 表单的 HTML 属性 novalidate
342+ ### 表单的 novalidate 属性
201343
202344表单元素的 HTML 属性` novalidate ` ,可以关闭浏览器的自动校验。
203345
@@ -206,6 +348,12 @@ document.getElementById('prompt').innerHTML = txt;
206348</form >
207349```
208350
351+ 这个属性也可以在脚本里设置。
352+
353+ ``` javascript
354+ form .noValidate = true ;
355+ ```
356+
209357如果表单元素没有设置` novalidate ` 属性,那么提交按钮(` <button> ` 或` <input> ` 元素)的` formnovalidate ` 属性也有同样的作用。
210358
211359``` html
@@ -351,4 +499,52 @@ The second line.
351499
352500上面的 HTML 代码中,file 控件的` multiple ` 属性,指定可以一次选择多个文件;如果没有这个属性,则一次只能选择一个文件。
353501
502+ ``` javascript
503+ var fileSelect = document .getElementById (' file' );
504+ var files = fileSelect .files ;
505+ ```
506+
507+ 然后,新建一个 FormData 实例对象,模拟发送到服务器的表单数据,把选中的文件添加到这个对象上面。
508+
509+ ``` javascript
510+ var formData = new FormData ();
511+
512+ for (var i = 0 ; i < files .length ; i++ ) {
513+ var file = files[i];
514+
515+ // 只上传图片文件
516+ if (! file .type .match (' image.*' )) {
517+ continue ;
518+ }
519+
520+ formData .append (' photos[]' , file, file .name );
521+ }
522+ ```
523+
524+ 最后,使用 Ajax 向服务器上传文件。
525+
526+ ``` javascript
527+ var xhr = new XMLHttpRequest ();
528+
529+ xhr .open (' POST' , ' handler.php' , true );
530+
531+ xhr .onload = function () {
532+ if (xhr .status !== 200 ) {
533+ console .log (' An error occurred!' );
534+ }
535+ };
536+
537+ xhr .send (formData);
538+ ```
539+
540+ 除了发送 FormData 实例,也可以直接 AJAX 发送文件。
541+
542+ ``` javascript
543+ var file = document .getElementById (' test-input' ).files [0 ];
544+ var xhr = new XMLHttpRequest ();
545+
546+ xhr .open (' POST' , ' myserver/uploads' );
547+ xhr .setRequestHeader (' Content-Type' , file .type );
548+ xhr .send (file);
549+ ```
354550
0 commit comments