当我们使用ajax传递的参数值较多时,参数的值的获取以及拼接都很麻烦,这时我们就可以使用 formdata对象,可以方便我们的操做,更为重要的是我们可以传递二级制的文件了,比如图片,这在普通的方法里是办不到的。
FormData对象作用:
1.模拟HTML表单,相当于将HTML表单映射成表单对象,自动将表单对象中的数据拼接成请求参数的格式。
2.异步上传二进制文件
formdata对象使用方法:
1.准备HTML表单。
<!-- 创建普通的html表单 -->
<form id="form">
<input type="text" name="username">
<input type="password" name="password">
<input type="button" id="btn" value="提交">
</form>
2.将HTML表单转化为formdata对象
var form = document.getElementById('form');
const formData = new FormData(form);
创建一个新的formdata对象将表单传进去,会自动帮我们把表单转化为参数所需要的格式。
3.提交表单对象。
xhr.send(formData);
注意:**
1.FormData对象不能用于get请求,因为对象需要被传递到send方法中,而get请求方式的请求参数只能放在请求地址的后面。
2.服务器端bodyParser模块不能解析FormData对象表单数据,我们需要使用formidable模块进行解析**
客户端代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<!-- 创建普通的html表单 -->
<form id="form">
<input type="text" name="username">
<input type="password" name="password">
<input type="button" id="btn" value="提交">
</form>
<script type="text/javascript">
var form = document.getElementById('form')
var btn = document.getElementById('btn');
//创建点击事件发送客户端请求
btn.onclick = function () {
//实例化一个FormData表单对象
const formData = new FormData(form);
// console.log(formData.get('username'));
// formData.set('username', '小朋友')
// 实例化一个ajax对象
const xhr = new XMLHttpRequest()
xhr.open('post', 'http://localhost:2000/formData');
//将表单里的信息以formData对象发送到服务器
xhr.send(formData);
xhr.onload = function () {
if (xhr.status == 200) {
console.log(xhr.responseText);
}
}
}
</script>
</body>
</html>
服务器端代码如下:
//创建post请求,请求地址是/formData
app.post('/formData', (req, res) => {
//创建formidable表单解析对象
const form = new formidable.IncomingForm();
//解析客户端传过来的FormData对象
form.parse(req, (err, fields, files) => {
res.send(fields);
});
});
这里我们将fields响应回客户端,这个参数里面就是保持了表单的普通请求参数,当然,第三个参数里面保存的就是表单中的二进制参数。
formdata 对象的实例方法
这些方法是对表单中数据的操作,因为点击提交后不会立刻将数据传给服务器端,会先进行校验。
1.获取表单对象中属性的值。
在这里插入图片描述
传入的值就是表单中input的name名
2.设置表单对象中属性的值
在这里插入图片描述
第一个参数就是表单中input的name名,第二个是要修改的值内容。
注意:如果表单中没有这一项,那么会自动创建这一项。
3.删除表单对象中属性的值
在这里插入图片描述
4.向表单对象中追加属性值。
在这里插入图片描述
这里说一下 set方法和 append方法的区别:
formdata 二进制文件上传
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="/assets/bootstrap/dist/css/bootstrap.min.css">
<style type="text/css">
.container {
padding-top: 60px;
}
.padding {
padding: 5px 0 20px 0;
}
</style>
</head>
<body>
<div class="container">
<div class="form-group">
<label>请选择文件</label>
<input type="file" id="file">
<div class="padding" id="box">
<!--<img src="" class="img-rounded img-responsive">-->
</div>
<div class="progress">
<div class="progress-bar" style="width: 0%;" id="bar">0%</div>
</div>
</div>
</div>
<script>
var file = document.getElementById('file')
var bar = document.getElementById('bar')
var box = document.getElementById('box')
var formData = new FormData()
file.onchange = function () {
formData.append('attrName', this.files[0])
var xhr = new XMLHttpRequest();
xhr.open('post', 'http://localhost:2000/upload')
//进度条展示
xhr.upload.onprogress = function (ev) {
// 当前上传的进度
// ev.loaded / ev.total*100 + '%'
const progress = ev.loaded / ev.total * 100 + '%';
// 将上传进度值给对应的样式
bar.style.width = progress;
bar.innerHTML = progress;
}
xhr.send(formData);
xhr.onload = function () {
// 用result来接收服务器端传过来的响应结果,需要先转换为json对象
var result = JSON.parse(xhr.responseText)
var img = document.createElement('img')
img.src = result.path;
// 当图片加载完成后,调用该函数显示图片,将img节点添加到box容器中
img.onload = function () {
box.appendChild(img);
}
if (xhr.status == 200) {
console.log(xhr.responseText);
} else {
console.log('错误' + xhr.status);
}
}
}
</script>
</body>
</html>
这里我们用监听一个用户选择文件时的onchange事件,在里面我们要先创建一个空的formdata对象用来存储用户选着文件,然后在使用formdata下面的append方法向表单中追加数据,用户存储的文件在files属性中,这个属性是一个集合。
服务器端
app.post('/upload', (req, res) => {
// 创建表单解析对象
const form = new formidable.IncomingForm();
//获取接受文件的文件夹路径
form.uploadDir = path.join(__dirname, 'public', 'uploads');
form.keepExtensions = true;
//解析客户端传过来的表单对象。
form.parse(req, (err, fields, files) => {
res.send({
//files.attrName是描述上传文件的一些信息,里面有大小,路径,文件格式等等。
//files.attrName.path是上传文件的路径,用split函数将原来的路径字符串以public分割成一个数组,然后[1]就是数组元素中的后一个元素
path: files.attrName.path.split('public')[1]
});
})
})
app.listen(2000);
console.log('服务器启动成功');