formdata上傳文件
1.關(guān)于formdata
XMLHttpRequest Level 2 添加了一個(gè)新的接口——FormData。利用 FormData 對(duì)象,我們可以通過(guò) JavaScript 用一些鍵值對(duì)來(lái)模擬一系列表單控件,我們還可以使用 XMLHttpRequest 的 send() 方法來(lái)異步的提交表單。與普通的 Ajax 相比,使用 FormData 的最大優(yōu)點(diǎn)就是我們可以異步上傳二進(jìn)制文件。
FormData的api
方法一:
創(chuàng)建一個(gè)空FormData對(duì)象:
var formData = new FormData()
使用FormData.append添加一個(gè)鍵/值對(duì):
formData.append('username', 'Chris');
方法二:利用form表單傳遞給formdata
<form id="myForm" name="myForm">
<div>
<label for="username">Enter name:</label>
<input type="text" id="username" name="username">
</div>
<div>
<label for="useracc">Enter account number:</label>
<input type="text" id="useracc" name="useracc">
</div>
<div>
<label for="userfile">Upload file:</label>
<input type="file" id="userfile" name="userfile">
</div>
<input type="submit" value="Submit!">
</form>
var myForm = document.getElementById('myForm');
formData = new FormData(myForm);
2.formdata上傳文件
目錄結(jié)構(gòu)
.
├── index.js
├── node_modules
├── package.json
└── public
├── index.html
└── uploads
客戶端代碼
<!-- index.html -->
<input id="file" type="file">
<button id="btn">點(diǎn)擊上傳</button>
<img id="img" src="" alt="">
<script>
var btn = document.getElementById("btn"),
file = document.getElementById("file"),
img = document.getElementById("img");
btn.onclick = function () {
// 獲取文件
var upload_file = file.files[0],
formdata = new FormData(),
xhr = new XMLHttpRequest();
formdata.append('date',new Date().toLocaleString());
// 將文件添加到formdata對(duì)象中,(注:下面的file字段名在node中有用)
formdata.append('file', upload_file);
xhr.open("POST", "/upload", true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
img.src = xhr.responseText;
}
}
xhr.send(formdata);
}
</script>
服務(wù)端代碼
// index.js
var express = require("express");
var app = express();
/*
1. 保存在文件夾中的文件為二進(jìn)制,所以想在本地點(diǎn)開(kāi)能預(yù)覽的,取消下面fs模塊引用的注釋
2. 并在命令行中輸入 npm install fs --save
*/
// var fs = require("fs");
var multer = require("multer");
// 這里dest對(duì)應(yīng)的值是你要將上傳的文件存的文件夾
var upload = multer({dest:'./public/uploads'});
app.use(express.static('./public'));
app.post("/upload", upload.single('file'),(req, res) => {
// req.file 是 'file' 文件的信息 (前端傳遞的文件類型在req.file中獲取)
// req.body 將具有文本域數(shù)據(jù),如果存在的話 。(上面前端代碼中傳遞的date字段在req.body中獲?。? console.log(req.body) //{ date: '2018/1/20 下午5:25:56' }
// ---------- 因?yàn)楸4娴奈募槎M(jìn)制,取消下面代碼塊注釋可讓保存的圖片文件在本地文件夾中預(yù)覽------
/*
var file_type;
if (req.file.mimetype.split('/')[0] == 'image') file_type = '.' + req.file.mimetype.split('/')[1];
if (file_type) {
fs.rename(req.file.path, req.file.path + file_type, function (err, doc) {
if (err) {
console.error(err);
return;
}
console.log('55');
res.send('./uploads/' + req.file.filename + file_type)
})
return;
}
*/
// ---------------------
res.send('./uploads/' + req.file.filename)
})
app.listen(9999);
接下來(lái)解釋下上述代碼
上面的例子是上傳圖片,服務(wù)端傳回圖片路徑進(jìn)行展示。上傳其他文件同理!
index.js中依賴express、multer 可以通過(guò)npm install express multer --save進(jìn)行安裝,當(dāng)然你也可以不使用express。
接下去重點(diǎn)講述下multer:
1.安裝:
npm install --save multer
2.使用:
multer(opts)
Multer 接受一個(gè) options 對(duì)象,其中最基本的是 dest 屬性,這將告訴 Multer 將上傳文件保存在哪。如果你省略 options 對(duì)象,這些文件將保存在內(nèi)存中,永遠(yuǎn)不會(huì)寫入磁盤。通常,只需要設(shè)置 dest 屬性 像這樣:
var upload = multer({ dest: 'uploads/' }) // dest對(duì)應(yīng)的值就是你想文件存儲(chǔ)的文件夾
.single(fieldname)
接受一個(gè)以 fieldname 命名的文件。這個(gè)文件的信息保存在 req.file。(這里的fieldname指的是formdata.append("file",文件)中的'file'字段其他方法詳見(jiàn)multer文檔
Multer 會(huì)添加一個(gè) body 對(duì)象 以及 file 或 files 對(duì)象 到 express 的 request 對(duì)象中。body 對(duì)象包含表單的文本域信息,file 或 files 對(duì)象包含對(duì)象表單上傳的文件信息。
app.post("/upload", upload.single('file'),(req, res) => {
// req.file 是 'file' 文件的信息 (前端傳遞的文件類型在req.file中獲?。? // req.body 將具有文本域數(shù)據(jù),如果存在的話 。(上面前端代碼中傳遞的date字段在req.body中獲?。? console.log(req.body) // { date: '2018/1/20 下午5:25:56' }
res.send('./uploads/'+req.file.filename)
})
注意事項(xiàng):
一、formdata在控制臺(tái)打印為空

可通過(guò)下面方法獲?。?
var formData = new FormData();
formData.append('username', 'Chris');
formData.append('username', 'Bob');
// get()函數(shù)只會(huì)返回username附加的第一個(gè)值
formData.get('username'); // Returns "Chris"
// getAll()函數(shù)將返回username一個(gè)數(shù)組中的兩個(gè)值:
formData.getAll('username'); // Returns ["Chris", "Bob"]
二、如果formdata添加文件成功了的話,還是上傳失敗,可以看看頭部是否為multipart/form-data
文章都是學(xué)習(xí)過(guò)程中的總結(jié),如果發(fā)現(xiàn)錯(cuò)誤,歡迎留言指出,如果你熱愛(ài)分享知識(shí)那就加入我們吧 群號(hào):431679880