form 表单基本属性
属性 | 说明 |
---|---|
action | 表单提交地址 |
method | 表单提交方式, 常用的有 get / post |
autocomplete | 表单自动补全 |
novalidate | 不验证表单 |
enctype | 规定被提交数据的编码(默认:url-encoded); 当提交的表单中有文件域时, 应设置为 multipart/form-data |
表单的同步提交和异步提交
常见的表单提交方式有 get / post, 通过 method 属性来设置
- form 内的所有要提交的表单元素都必须具有 name 属性
表单的同步提交
form 表单默认的提交行为是同步提交, 且默认提交方式为 get
- 意思是, 当 form 具有
submit
类型的表单元素时, 不设置 method, 点击提交按钮或者调用 form 元素的 submit() 方法表单也会提交1
2
3<form method="post" action="/register" id="register-form">
</form>
- 同步提交方式页面会转圈锁死
- 同步提交服务端会将响应数据直接渲染到浏览器页面上覆盖掉原来的页面
- 同步提交在服务端没法操作 dom 元素, 不能给 dom 元素添加样式
表单的异步提交
使用 AJAX 方式提交表单就是异步提交
- ⚠️ 异步提交需要先阻止表单的同步提交行为
1
2
3
4
5
6$('form').submit(function (e) {
e.preventDefault()
$.ajax({
......
})
})
- 异步提交页面不会刷新
- 异步提交服务端会将响应数据传递给 AJAX 响应处理函数
阻止表单的默认提交
event.preventDefault()
1 | form.onsubmit = function (e) { |
get 提交表单
提交的数据会以 ?key=value&key1=value1
的形式出现在 url 地址中
post 提交表单
提交的数据可以在 控制面板 => NetWork => 请求地址 => Request => Form Data 中查看
有文件域的表单提交
⚠️ 带有文件域的表单提交
- 类型必须是
post
- 必须将表单的
enctype
设置为multipart/form-data
- 否则, 文件不传输
1
2
3
4
5
6<form action="/" method="post" enctype="multipart/form-data">
<input type="text" name="name" /> <br>
...
<input type="file" name="avatar" />
<input type="submit" value="提交" />
</form>
- 否则, 文件不传输
带文件域的表单同步提交
服务端 接收具有文件域的表单请求需要使用第三方包 formidable
使用
1
yarn add formidable
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
32const express = require('express');
const formidable = require('formidable');
const path = require('path')
const app = express();
app.get('/', (req, res) => {
res.send('form.html')
})
app.post('/api/upload', (req, res, next) => {
const form = formidable({ multiples: true }) // options
form.parse(req, (err, fields, files) => {
// err —— 可能发生的错误对象
// fileds —— 普通的表单字段,是对象形式
// files —— 文件内容数据信息,是对象形式
if (err) {
return next(err)
}
// res.json({ fields, files })
const body = fileds
body.image = '/uploads/' + path.basename(files.avatar.path)
res.json(body)
})
})
app.listen(3000, () => {
console.log('Server is running......')
})-
1
2
3
4
5const form = formidable({
multiples: true,
uploadDir: '/uploads', // 指定文件上传目录
keepExtensions: true // 是否保留文件后缀名
})
带文件域的表单异步提交
⚠️ $ajax 默认提交的数据 data: $(this).serialize() 中是 不带文件域内容 的,就是说默认不能提交文件内容
如何解决?
用插件 ajaxFileUpload()
- 先通过图片提交接口提交图片
- 再通过 ajax 提交普通表单数据
- 可以实现图片预览
-
- 文件域和普通表单数据组成 formData 对象一起提交
- 可以通过 FileReader 实例对象实现图片预览
1
2
3var formData = new FormData([可以传递 htmlFormElement 元素])
// 把 file 追加到 formData 里
formData.append('avatar', $('[type=file]')[0].files[0])1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17var formData = new FormData(document.querySelector("form"));
$.ajax({
url: "/ads/add",
type: "POST",
data: formData, // 带文件域的数据
// 不处理数据, 当 data 的值为 formData 对象的时候, 一定要设置, 否则还是走同步提交
processData: false,
// 不设置内容类型,当提交一个 formdata 对象的时候,一定要设置,否则 jQuery 会默认把 content-type 设置为 x-www-urlencoded ,无法提交文件
contentType: false,
success: function (data) {
}
})1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<body>
<!--实现图片的实时预览 onchange改变元素后触发方法-->
<from>
文件: <input type="file" name="myFile" id="myFile" multiple onchange="getFileContext()"><br>
<img id="img"><br>
<input type="submit">
</from>
<script>
function getFileContext() {
var reader=new FileReader();
//需要的参数是图片
var file=document.querySelector("#myFile").files;
// 没有返回值,将其结果储存在result中,无法判断文件是否读完
reader.readAsDataURL(file[0]);
reader.onload=function () {
// 展示出来:得到的reader.result为二进制文件base64 data:image/jpeg;base64...
console.log(reader.result);
document.querySelector("#img").src=reader.result;
}
}
</script>
</body>
form 在 jQuery 中的方法
serialize()
- 在 ajax post 请求中将用作提交的表单元素的值编译成
name=value&name1=value1
字符串1
2var ret = $('form').serialize()
console.log(ret)
- 在 ajax post 请求中将用作提交的表单元素的值编译成
serializeArray() (不好用)
- 将用作提交的表单元素的值编译成拥有 name 和 value 对象组成的数组
submit()
- 为 submit 事件绑定一个处理函数, 或触发元素上的 submit 事件
- 当参数 function 没有给出时, 触发当前表单的 submit 事件, 并且执行默认的表单提交行为, 除非阻止表单默认行为
1
2
3
4
5
6
7
8$('form').submit(function (e) {
// 阻止表单默认同步提交行为
e.preventDefault()
// 异步提交
$.ajax({
......
})
})