form
标签标签用于为用户输入创建HTML表单,向服务器传输数据。
表单能够包含input
元素,比如文本字段、复选框、单选框、提交按钮等等。表单还可以包含menus
、textarea
、fieldset
、legend
和label
元素。
注释:form 元素是块级元素,其前后会产生折行。
<form id="myForm" action="http://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会需要知道请求的返回值,这个时候,浏览器发出跨域请求,需要获得授权才可以成功请求,否则是会拒绝的。
FormData
对象XMLHttpRequest Level2新提那家的接口,利用FormData
对象,可以通过一些键值对来模拟一系列表单空间,可以用XMLHttpRequest的send
方法来提交表单。
使用FormData
的最大优点是可以异步上传一个二进制文件。
FormData
对象的APIappend
: 用来向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')
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 = 'hey!'; // 新文件的正文...
const blob = new Blob([content], { type: "text/xml"});
formData.append("webmasterfile", blob);
const request = new XMLHttpRequest();
request.open("POST", "http://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
对象。
FormData
对象想要构造一个包含Form表单数据的FormData对象,需要在创建FormData对象时指定表单的元素。
const formData = new FormData(someFormElement);
还以最上面的表单为例,
const url = 'http://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");
使用append()
方法时,可以通过第三个可选参数设置发送请求的头Content-Disposition
指定文件名。如果不指定文件名(或者不支持该参数时),将使用名字“blob”。
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对象
serialize()
方法可以不使用FormData
对象,使用jQuery的serialize()
方法将表单结果序列化:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Form-Datatitle>
<script SRC="../lib/jquery.min.js">script>
head>
<body>
<form id="form">
<label><input type="radio" name="myInput1" value="A"><span>Aspan>label>
<label><input type="radio" name="myInput1" value="B"><span>Bspan>label>
<label><input type="radio" name="myInput1" value="C"><span>Cspan>label>
<label><span>输入你的屁话span><input type="text" name="bullshit">label>
form>
<div>
<button id="btn">clickbutton>
<span>选择结果:span><span id="result">span>
div>
<script>
$('#btn').on('click', function () {
$('#result').text($("#form").serialize())
})
script>
body>
html>
这个方法只能序列化表单的数据,但是对于文件(比如上传文件)则无法实现,这时候还是要使用FromData
对象了。