<form> 标签用于为用户输入创建 html 表单, 向服务器传输数据.
表单能够包含 input 元素, 比如文本字段, 复选框, 单选框, 提交按钮等等. 表单还可以包含 menus,textarea,fieldset,legend 和 label 元素.
注释: form 元素是块级元素, 其前后会产生折行.
<form id="myForm" action="https://www.w3school.com.cn/example/html/form_action.asp">
<label > 姓名:
<input name="username">
</label>
<br>
<label > 性别:
<input type="radio" name="gender" value="male" checked > 男
<input type="radio" name="gender" value="female">女</label>
<br>
<label > 住址:
<select name="address">
<option value="beijing" selected > 北京</option>
<option value="nanjing">南京</option>
<option value="tokyo">东京</option>
</select>
</label>
<button type="submit" id="submit">提交</button>
<button type="reset">重置</button>
</form>
在一个表单里面, action 规定当提交表单时向何处发送表单数据. 当点击 form 表单内, type 为 submit 的按钮时, 会将表单提交到 action 对应的地址, 而点击 type 为 reset 的按钮时, 表单会被重置
想要阻止提交或者重置行为, 需要使用 e.preventDefault()
注意, 通过 form 的 action 发送表单时, 是不受跨域的限制的, 原因是:
跨域指的是 "跨域资源共享(Cross-Origin Resource Sharing,CORS)". 当一个资源从与改资源本身所在服务器的不同的域或不同的端口请求一个资源时, 资源会发起一个跨域 HTTP 请求.
表单的提交方式有两种, 一种是直接指定表单的 action. 一种是 ajax 接手控制请求.
直接使用 action 的时候, 是直接把请求交给了 action 里面的域, 本身页面不会去管他的请求结果, 后面的步骤交给了 action 里面的域. 好比:
<from action="baidu.com">
// you form filed
</from>
上面这个表单提交后, 剩余的操作就交给了 action 里面的域 baidu.com, 本页面的逻辑和这个表单没啥关系, 由于不关系请求的响应, 所以浏览器认为是安全的.
而使用 ajax 来控制 form 的请求的时候, 页面 js 会需要知道请求的返回值, 这个时候, 浏览器发出跨域请求, 需要获得授权才可以成功请求, 否则是会拒绝的.
2 FormData 对象
XMLHttpRequest Level2 新提那家的接口, 利用 FormData 对象, 可以通过一些键值对来模拟一系列表单空间, 可以用 XMLHttpRequest 的 send 方法来提交表单.
使用 FormData 的最大优点是可以异步上传一个二进制文件.
3 FormData 对象的 API
append: 用来向 FormData 对象添加键值对
- delete
- get
- getAll
- has
- set
- keys
- values
- forEach
- - entries
FormData 对象的操作方法, 全部在原型中, 自己本身没任何的属性及方法.
- let formData = new FormData()
- formData.append('user', 'zhang')
- // 获取
- formData.get('user') //zhang
- // 删除
- formData.delete('user')
4 从零创建一个 FormData 对象
- const formData = new FormData();
- formData.append("username", "Groucho");
- formData.append("accountnum", 123456); // 数字 123456 会被立即转换成字符串 "123456"
- // HTML 文件类型 input, 由用户选择
- formData.append("userfile", fileInputElement.files[0]);
- // Blob 对象
- const content = '<a id="a"><b id="b">hey!</b></a>'; // 新文件的正文...
- const blob = new Blob([content], { type: "text/xml"});
- formData.append("webmasterfile", blob);
- const request = new XMLHttpRequest();
- request.open("POST", "https://foo.com/submitform.php");
- request.send(formData);
注意: 字段 userfile 和 webmasterfile 都包含一个文件. 字段 accountnum 是数字类型, 它将被 FormData.append()方法转换成字符串类型 FormData 对象的字段类型可以是 Blob,File, 或者 string: 如果它的字段类型不是 Blob 也不是 File, 则会被转换成字符串类型.
一个 Blob 对象表示一个不可变的, 原始数据的类似文件对象. Blob 表示的数据不一定是一个 JavaScript 原生格式. File 接口基于 Blob, 继承 blob 功能并将其扩展为支持用户系统上的文件. 你可以通过 Blob()构造函数创建一个 Blob 对象.
5 通过 HTML 表单创建 FormData 对象
想要构造一个包含 Form 表单数据的 FormData 对象, 需要在创建 FormData 对象时指定表单的元素.
const formData = new FormData(someFormElement);
还以最上面的表单为例,
- const url = 'https://www.w3school.com.cn/example/html/form_action.asp';
- const myForm = document.querySelector('#myForm');
- const submit = document.querySelector('#submit');
- submit.addEventListener('click', function(e) {
- const formData = new FormData(myForm);
- const request = new XMLHttpRequest();
- request.open('POST', url);
- formData.append('hair', 'black');
- request.send(formData);
- e.preventDefault()
- })
还可以在创建一个包含 Form 表单数据的 FormData 对象之后和发送请求之前, 附加额外的数据到 FormData 对象里
使用 FromData 对象上传文件
还可以使用 FormData 上传文件. 使用的时候需要在表单中添加一个文件类型的 input:
<form enctype="multipart/form-data" method="post" name="fileinfo">
<label>File to stash:</label>
<input type="file" name="file" required />
</form>
然后启用下面发送请求:
- const form = document.forms.namedItem("fileinfo");
- form.addEventListener('submit', function(ev) {
- const oData = new FormData(form);
- oData.appen('extraName', 'extraValue')
- const request = new XMLHttpRequest();
- request.open('POST', 'some.php', true);
- request.onreadystatechange = function() {
- if (request.status == 200 && request.readystate === 4) {
- console.log('发送成功')
- }
- }
- request.send(oData);
- ev.preventDefault();
- })
上面:
DOM namedItem()方法集合中取回带有指定名称的节点或元素. 返回具有指定 id 或 name 属性的元素或节点. 如果 HTMLCollection 中没有这样的节点, 则返回 null.
如果 FormData 对象是通过表单创建的, 则表单中指定的请求方式会被应用到方法 open()中.
还可以直接向 FormData 对象附加 File 或 Blob 类型的文件, 如下所示:
- data.append("myfile", myBlob, "filename.txt");
- 1
使用 append()方法时, 可以通过第三个可选参数设置发送请求的头 Content-Disposition 指定文件名. 如果不指定文件名(或者不支持该参数时), 将使用名字 "blob".
6 使用 jQuery
6.1 通过 jQuery 使用 FormData 对象
- $.ajax({
- url: 'file.php',
- type: 'POST',
- data: formdata, // 上传 formdata 封装的数据
- dataType: 'JSON',
- cache: false, // 不缓存
- processData: false, // jQuery 不要去处理发送的数据
- contentType: false, // jQuery 不要去设置 Content-Type 请求头
- success: function(data) { // 成功回调
- console.log(data);
- }
- });
注意: new FormData 的参数是一个 DOM 对象, 而非 jQuery 对象
6.2 serialize()方法
可以不使用 FormData 对象, 使用 jQuery 的 serialize()方法将表单结果序列化:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Form-Data</title>
- <script SRC="../lib/jquery.min.js"></script>
- </head>
- <body>
- <form id="form">
- <label><input type="radio" name="myInput1" value="A"><span>A</span></label>
- <label><input type="radio" name="myInput1" value="B"><span>B</span></label>
- <label><input type="radio" name="myInput1" value="C"><span>C</span></label>
- <label><span > 输入你的屁话</span><input type="text" name="bullshit"></label>
- </form>
- <p>
- <button id="btn">click</button>
- <span > 选择结果:</span><span id="result"></span>
- </p>
- <script>
- $('#btn').on('click', function () {
- $('#result').text($("#form").serialize())
- })
- </script>
- </body>
- </html>
这个方法只能序列化表单的数据, 但是对于文件 (比如上传文件) 则无法实现, 这时候还是要使用 FromData 对象了.
来源: https://www.2cto.com/kf/201807/761952.html