FormData对象以及上传普通表单和二进制文件进度条的展示
作用
-
模拟HTML表单,相当于将表单映射成表单对象,自动将表单对象中的数据拼接成请求参数的格式
-
异步上传二进制文件
模拟HTML表单
-
准备表单
<form id="form"> <input type="text" name="username"> <input type="password" name="password"> <input type="button"> </form>
-
将表单转换为
formData
对象let form = document.getElementById('form') let formData = new FormData(form)
-
提交表单
注意:
formData
数据不能用于get请求xhr.send(formData)
-
demo代码
-
前端代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <form id="form"> <input type="text" name="username"> <input type="password" name="password"> <input type="button" id="btn" value="提交"> </form> <script> // 获取对象 let btn = document.getElementById('btn') // 获取表单 let form = document.getElementById('form') // 为按钮添加点击事件 btn.onclick = function(){ // 将普通的html表单转换为表单对象 let formData = new FormData(form) // 创建ajax对象 let xhr = new XMLHttpRequest() // 对ajax对象进行配置 xhr.open('post' , 'http://localhost:5000/formData') // 发送ajax请求 xhr.send(formData) // 监听xhr对象的 onload 事件 xhr.onload = function(){ if(xhr.status == 200){ console.log(xhr.responseText) } } } </script> </body> </html>
-
后端代码
const express = require('express') const bodyParser = require('body-parser') const cors = require('cors') const formidable = require('formidable') var app = express() // 解决跨域 app.use(cors()) //配置解析 post app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) app.post('/formData' , function(req , res){ // 1. 创建表单解析对象 const form = new formidable.IncomingForm() // 2. 解析表单 form.parse(req , (err, fields, files) => { // err 错误对象 如果表单解析失败 err里面存储错误信息 如果表单解析成功 err为null // fields 对象类型 保存普通表单数据 // files 对象类型 保存上传文件相关数据 if(err){ console.log(err) return res.send('上传失败') } return res.send(fields) }) }) app.listen(5000 , function() { console.log('Running...') })
-
FormData 对象的实例方法
-
获取表单对象中的属性的值
get
formData.get('key')
-
设置表单对象中属性的值
set
如果key存在则覆盖,不存在则直接创建
formData.set('key' , 'value')
-
删除表单对象中的属性值
formData.delete('key')
-
向表单中追加属性值
formData.append('key' , 'value')
注意:在原有属性已存在的情况下,set方法会覆盖原来的属性值,append方法会保留原来的属性值。
FormData 二进制文件的上传
- 上传二进制文件:
<input type="file" id="file">
let file = document.getElementById('file')
file.onchange = function(){
let formData = new FormData()
formData.append('demo' , this.files[0])
// 创建ajax对象
let xhr = new XMLHttpRequest()
// 对ajax对象进行配置
xhr.open('post' , 'http://localhost:5000/upload')
// 发送ajax请求
xhr.send(formData)
// 监听xhr对象的 onload 事件
xhr.onload = function(){
if(xhr.status == 200){
console.log(xhr.responseText)
}
}
}
- 上传进度的展示
//当用户选择文件的时候
file.onchange = function(){
//文件上传过程中持续触发 onprogress事件
xhr.upload.onprogress = function(e){
// 当前上传文件大小/文件总大小 再将结果转换为百分数
bar.style.width = (e.loaded / e.total) * 100 + '%'
}
}
- demo代码:
-
目录结构:
-
前端代码
demo2.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> <title>Document</title> <style> .main{ width: 80%; padding: 40px; } </style> </head> <body> <div class="main"> <input type="file" id="file"> <div class="progress" style="margin-top: 20px;"> <div class="progress-bar" id="bar" style="width: 0%;">0%</div> </div> </div> <script> let file = document.getElementById('file') file.onchange = function(){ let formData = new FormData() formData.append('demo' , this.files[0]) // 创建ajax对象 let xhr = new XMLHttpRequest() // 对ajax对象进行配置 xhr.open('post' , 'http://localhost:5000/upload') xhr.upload.onprogress = function(e){ let bar = document.getElementById('bar') // 当前上传文件大小/文件总大小 再将结果转换为百分数 let pro = (e.loaded / e.total) * 100 + '%' // 设置进度条宽度 bar.style.width = pro // 将百分比显示在进度条中 bar.innerText = pro } // 发送ajax请求 xhr.send(formData) // 监听xhr对象的 onload 事件 xhr.onload = function(){ if(xhr.status == 200){ console.log(xhr.responseText) } } } </script> </body> </html>
-
后端代码
app.js
const express = require('express') const bodyParser = require('body-parser') const cors = require('cors') const path = require('path') const formidable = require('formidable') const template = require('art-template') var app = express() // 解决跨域 app.use(cors()) //配置解析 post app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) app.engine('html' , require('express-art-template')) app.get('/' , function(req , res){ res.render('demo2.html') }) app.post('/formData' , function(req , res){ // 1. 创建表单解析对象 const form = new formidable.IncomingForm() // 2. 解析表单 form.parse(req , (err, fields, files) => { // err 错误对象 如果表单解析失败 err里面存储错误信息 如果表单解析成功 err为null // fields 对象类型 保存普通表单数据 // files 对象类型 保存上传文件相关数据 if(err){ console.log(err) return res.send('上传失败') } return res.send(fields) }) }) app.post('/upload' , function(req , res){ // 1. 创建表单解析对象 const form = formidable({ multiples: true , keepExtensions: true }) // 2. 配置上传文件存放的位置 form.uploadDir = path.join( __dirname , 'public' , 'uploads' ) // 3. 解析表单 form.parse(req , (err, fields, files) => { // err 错误对象 如果表单解析失败 err里面存储错误信息 如果表单解析成功 err为null // fields 对象类型 保存普通表单数据 // files 对象类型 保存上传文件相关数据 res.send('ok') }) }) app.listen(5000 , function() { console.log('Running...') })
-