FormData
能將表單內的數據自動拼接成請求參數的格式
步驟:
前端:
和ajax配合,把表單資料傳給後端
var formData = new FormData(表單名稱)
`
`
`
xhr.send(formData)
後端:
已node為例,需要依靠模塊 ’ formidable ',創建以後再用其底下的 parse,把前端傳來的form格式解析
app.post('/formData', (req, res) => {
// 创建formidable表单解析对象
const form = new formidable.IncomingForm();
// 解析客户端传递过来的FormData对象
form.parse(req, (err, fields, files) => {
res.send(fields);
});
});
完整範例:
<form id='account'>
<input type="text" name='name'>
<input type="text" name='pasw'>
<input type="button" id="btn" value="send">
</form>
<div class="progress">
<div class="progress_bar" style="width: 0%;" id='bar'></div>
</div>
<script>
var file = document.querySelector('#file')
var account = document.querySelector('#account')
btn.onclick = function () {
var formData = new FormData(account)
var xhr = new XMLHttpRequest
xhr.open('post', 'http://localhost:3000/formData')
xhr.send(formData)
xhr.onload = function () {
if (xhr.status === 200) {
console.log(xhr.responseText);
}
}
}
此時前端收到得後端的返回值為:
{"name":"用戶輸入的帳號","pasw":"用戶輸入的密碼"}
formData除了能把表單解析成後端收到的參數外,還有很多方法可供使用
這裡介紹幾個基本的用法:
獲取表單屬性值
formdata.get(‘key’)
key則為表單元素的name值
btn.onclick = function () {
var formData = new FormData(account)
var xhr = new XMLHttpRequest
console.log(formData.get('pasw'));
`
`
`
`
向表單刪除屬性 :
formdata delet(‘key’)
此方法和get方法在使用上方法相同,它可以用在當客戶被要求’ 輸入密碼和再輸入一次密碼 ’ 時,在前端驗證密碼相同匹配後,只向後端發送一個密碼即可。
向表單設定屬性 :
formdata.set(‘key’,‘value’)
此方法可以設定表單內元素的屬性值,不管被輸入任何值最後都只會輸出set裡面的value值。
在屬性名稱已存在的狀況下,set屬性會替換/覆蓋原有的屬性元素。如果屬性名稱不存在,則set為新增一個屬性元素
console.log(formData.set( ' name ' , ' jack ' );
向表單追加屬性 :
formdata append(‘key’,‘value’)
此方法和set相似,不同的是如果指定的元素在表單裡已經存在的話,它不會覆蓋/替換,會將兩個元素(原有的,後來append的)都保留,但是在傳送給後端時雖然兩個參數都傳送,但是服務器端在默認情況下只會接收最後一個值
FormData二進制文件上傳:
二進制:視頻,音頻等…文件,利用ajax傳送時,只能選擇post為請求方式
file.onchange = function () {
var file = document.querySelector('#file')
創建空表單對象
var formData = new FormData(account)
//將用戶選擇的二進制文件追加到表單對象中
formData.append('attrName', this.files[0])
//配置ajax對象,注意請求方式必須為post
xhr.open('post', 'http://localhost:3000/upload')
xhr.send(formData)
}
}
後端接收二進制文件:
已node為例
uploadDir屬性為設定客戶上傳文件後,文件的儲存地方
keepExtensions為保留尚存文件的後墜名()
app.post('/upload', (req, res) => {
// 创建formidable表单解析对象
const form = new formidable.IncomingForm();
// 设置客户端上传文件的存储路径
form.uploadDir = path.join(__dirname, 'public', 'upload');
// 保留上传文件的后缀名字
form.keepExtensions = true
// 解析客户端传递过来的FormData对象
form.parse(req, (err, fields, files) => {
res.send('ok');
});
});
文件上傳進度條展示
在XMLHttpRequest下有個upload事件,和上傳有關的屬性都被存在裡面。
其中onprogerss事件,是在上傳過程中不斷被觸發,在事件對象中存了
’ loaded '表示已上傳的容量,total表示總容量。
將總容量除上已上傳容量後,在轉換成百分比,並將它賦值給html的元素,因為它是在上傳中會不斷觸發,也表示它會不斷賦值給元素的width,此時元素就能動起來並顯示進度!
完整代碼:
file.onchange = function () {
var file = document.querySelector('#file')
var bar = document.querySelector('#bar')
var formData = new FormData(account)
formData.append('attrName', this.files[0])
var xhr = new XMLHttpRequest
xhr.open('post', 'http://localhost:3000/upload')
xhr.upload.onprogress = function (ev) {
// ev.loaded 文件已经上传了多少
// ev.total 上传文件的总大小
var result = (ev.loaded / ev.total) * 100 + '%';
// 设置进度条的宽度
bar.style.width = result;
// 将百分比显示在进度条中
bar.innerHTML = result;
}
xhr.send(formData)
}
}
即時預覽上傳圖片
整體的思路是,客戶上傳圖片後,圖片會被存在後端伺服器中,後端在獲取圖片存在自己伺服器的地址,然後將地址返回給前端,前端則可以將這段path拼接給img標籤
前端:
記得要將客戶上傳的圖片加入form表單中,才能將客戶的圖片傳送給後端
img.onload ,其中的onload屬性是表示將在圖片全部加載完後,才執行某些動作
file.onchange = function () {
// 创建空的formData表单对象
var formData = new FormData();
// 将用户选择的文件追加到formData表单对象中
formData.append('attrName', this.files[0]);
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 对ajax对象进行配置
xhr.open('post', 'http://localhost:3000/upload');
// 发送ajax请求
xhr.send(formData);
// 监听服务器端响应给客户端的数据
xhr.onload = function () {
// 如果服务器端返回的http状态码为200
// 说明请求是成功的
if (xhr.status == 200) {
// 将服务器端返回的数据显示在控制台中
var result = JSON.parse(xhr.responseText);
// 动态创建img标签
var img = document.createElement('img');
// 给图片标签设置src属性
img.src = result.path;
// 当图片加载完成以后
img.onload = function () {
// 将图片显示在页面中
box.appendChild(img);
}
}
}
}
後端:
// 实现文件上传的路由
app.post('/upload', (req, res) => {
// 创建formidable表单解析对象
const form = new formidable.IncomingForm();
// 设置客户端上传文件的存储路径
form.uploadDir = path.join(__dirname, 'public', 'uploads');
// 保留上传文件的后缀名字
form.keepExtensions = true;
// 解析客户端传递过来的FormData对象
form.parse(req, (err, fields, files) => {
// 将客户端传递过来的文件地址响应到客户端
res.send({
path: files.attrName.path.split('public')[1]
});
});
});
完整代碼:
file.onchange = function () {
// 创建空的formData表单对象
var formData = new FormData();
// 将用户选择的文件追加到formData表单对象中
formData.append('attrName', this.files[0]);
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 对ajax对象进行配置
xhr.open('post', 'http://localhost:3000/upload');
// 在文件上传的过程中持续触发
xhr.upload.onprogress = function (ev) {
// ev.loaded 文件已经上传了多少
// ev.total 上传文件的总大小
var result = (ev.loaded / ev.total) * 100 + '%';
// 设置进度条的宽度
bar.style.width = result;
// 将百分比显示在进度条中
bar.innerHTML = result;
}
// 发送ajax请求
xhr.send(formData);
// 监听服务器端响应给客户端的数据
xhr.onload = function () {
// 如果服务器端返回的http状态码为200
// 说明请求是成功的
if (xhr.status == 200) {
// 将服务器端返回的数据显示在控制台中
var result = JSON.parse(xhr.responseText);
// 动态创建img标签
var img = document.createElement('img');
// 给图片标签设置src属性
img.src = result.path;
// 当图片加载完成以后
img.onload = function () {
// 将图片显示在页面中
box.appendChild(img);
}
}
}
}