前端實現文件上傳的類型為FormData
先熟悉下FormData的API
var fd=new FormData()//
fd.apend('name','張三');//為fd對象添加參數,以key=>value的鍵值對的形式
//或者用fd.set('name','張三')
要獲取formData中的值,不能直接打印console.log(fd),這樣是打印不出來值的,一定要用get()方法才能獲取,或者是用數組的方式遍歷
例如fd.forEach()方法
fd.get('user');
開始實現文件上傳
前端使用<input type='file'>標簽實現上傳
<form id='form'>
<label>姓名: <input type="text" id='user' name="user" /></label>
<input type="file" id="foo" name="foo" multiple="multiple">
</form>
其中multiple="multiple" 的參數表示可以選擇多張文件上傳
手寫ajax代碼如下
var user = document.getElementById('user');
var file = document.getElementById('foo');
var btn = document.getElementsByTagName('button')[0];
btn.onclick = () => {
var ajx = new XMLHttpRequest();
ajx.open("post", "/upload", true); //設置請求地址和路徑
var fd = new FormData();
fd.append('user', user.value);
fd.append('file',file.files[0]);
ajx.onreadystatechange = function () {
if (ajx.readyState == 4 && ajx.status == 200) {
console.log(ajx);
}
}
ajx.send(fd);
}
以上代碼要把獲取的user的值和文件轉換成FormData對象,其中獲取文件數據是通過[目標元素].files獲取,獲取的的值是類似于數組,因為可以是多個文件,所有需要做什么操作可以去遍歷一遍,要把表單數據統一轉換成FormData對象,可以不用append()方法一項項的去添加,可以利用表單元素的屬性進行操作
var fd = new FormData(document.getElementById('form'));
用這種方式每個輸入框必須要有name屬性,例如<input type='file' name='file'>
node配置服務端
上傳文件需要安裝一個中間件處理express-fileupload
npm install express-fileupload --save
早app.js中注冊一下
const fileUpload = require('express-fileupload');
app.use(fileUpload());
手寫后臺接口路由
var express = require('express');
var router = express.Router();
var path=require('path');
router.post('/upload', function(req, res, next) {
console.log(req.body);
let f = req.files.file;
f.mv(path.join(__dirname,'../public','upload',f.name), function(err) {
if(err){
return res.status(400).send("sdsdsdas");
}
res.send('文件上傳成功!');
});
});
module.exports = router;
以上代碼 let f = req.files.file;file為前的FormData對象的鍵值,
如果要上傳多個文件,input只需要加multiple="multiple"屬性
<inpurt type='file' multiple="multiple">
后臺代碼
router.post('/upload', function(req, res, next) {
let f = req.files.file;
let newFile =[].concat(f);
newFile.forEach((file,index)=>{
file.mv(path.join(__dirname,'../public','upload',file.name), function(err) {
if(err){
return res.status(400).send("sdsdsdas");
}
});
})
res.send('文件上傳成功!');
});
效果如下圖所示
上傳圖片前的圖片回顯
有時候需要上傳圖片,選擇圖片后需要先顯示而不是直接取后臺返回來的地址
html代碼
<form id='form'>
<label>姓名: <input type="text" id='user' name="user" /></label>
<input type="file" id="foo" name="file" multiple="multiple">
</form>
<!-- 圖片回顯 -->
<div class="image">
</div>
<button>提交</button>
js代碼
var form = document.getElementById('form');
var user = document.getElementById('user');
var btn = document.getElementsByTagName('button')[0];
var file = document.getElementById('foo');
var showImg = document.getElementsByClassName('image')[0];
file.onchange = (e) => {
const reader = new FileReader();
reader.readAsDataURL(file.files[0]);
var img = new Image();
reader.onloadend = (e) => {
img.src = reader.result;
showImg.appendChild(img);
}
}
btn.onclick = () => {
var ajx = new XMLHttpRequest();
ajx.open("post", "/upload", true);
var fd = new FormData(form);
ajx.onreadystatechange = function () {
if (ajx.readyState == 4 && ajx.status == 200) {
console.log(ajx);
}
}
ajx.send(fd);
}
其中的onChange方法是input標簽選擇圖片時觸發,此時需要知道FileReader對象的用法以及API
https://developer.mozilla.org/en-US/docs/Web/API/FileReader
github地址