單文件
- 只支持上傳一個文件。
- 上傳文件必須在全部其餘的 fields 後面,不然在拿到文件流時可能還獲取不到 fields
-
await pump(stream, writeStream)
; //寫入並銷燬當前流 (egg demo提供的)
前端
view
app/view/admin/focus/singleUpload.html
<form action="/admin/focus/doSingleUpload?_csrf=<%=csrf%>" method="post" enctype="multipart/form-data">
<ul>
<li> 圖片名稱: <input type="text" name="title" /></li>
<li> 文件: <input type="file" name="pic" /></li>
<li>
圖片描述:
<textarea name="description" id="" cols="60" rows="8"></textarea>
</li>
<li>
<br />
<button type="submit" class="btn btn-primary">提交</button>
</li>
</ul>
</form>
後臺
router.js
router.get('/admin/focus/singleUpload', controller.admin.focus.singleUpload);
router.post('/admin/focus/doSingleUpload', controller.admin.focus.doSingleUpload);
controuler
app/controller/admin/focus.js
async doSingleUpload() {
const stream = await this.ctx.getFileStream(); //獲取表單提交的數據
if (!stream.filename) { //注意若是沒有傳入圖片直接返回
return;
}
// console.log(JSON.stringify(stream))
// 上傳目錄
// "filename":"c:/images/291051166-5b20eca6448e8_articlex.png", path.basename => 291051166-5b20eca6448e8_articlex.png
const target = 'app/public/admin/upload/' + path.basename(stream.filename);
const writeStream = fs.createWriteStream(target);
await pump(stream, writeStream); //stream.pipe(writeStream); //能夠用, 可是不建議,由於不能處理失敗的狀況
this.ctx.body = {
url: target,
fields: stream.fields //表單的其餘數據
}
}
效果
![clipboard.png clipboard.png](http://static.javashuo.com/static/loading.gif)
![clipboard.png clipboard.png](http://static.javashuo.com/static/loading.gif)
![clipboard.png clipboard.png](http://static.javashuo.com/static/loading.gif)
多文件
- { autoFields: true }:能夠將除了文件的其它字段提取到 parts 的 filed 中
前端
view
app/view/admin/focus/multi.html
<form action="/admin/focus/doMultiUpload?_csrf=<%=csrf%>" method="post" enctype="multipart/form-data">
<ul>
<li> 圖片名稱: <input type="text" name="title"/></li>
<li> 圖片1: <input type="file" name="face"/></li>
<li> 圖片2: <input type="file" name="pic2"/></li>
<li>
圖片描述:
<textarea name="description" id="" cols="60" rows="8"></textarea>
</li>
<li>
<br/>
<button type="submit" class="btn btn-primary">提交</button>
</li>
</ul>
</form>
後臺
router.js
router.get('/admin/focus/multi', controller.admin.focus.multi);
router.post('/admin/focus/doMultiUpload', controller.admin.focus.doMultiUpload);
controller
app/controller/admin/focus.js
async doMultiUpload() {
//{ autoFields: true }:能夠將除了文件的其它字段提取到 parts 的 filed 中
//多個圖片/文件
const parts = this.ctx.multipart({
autoFields: true
});
const files = [];
let stream;
while ((stream = await parts()) != null) {
if (!stream.filename) { //注意若是沒有傳入圖片直接返回
return;
}
const fieldname = stream.fieldname; //file表單的名字 face
const target = 'app/public/admin/upload/' + path.basename(stream.filename);
const writeStream = fs.createWriteStream(target);
await pump(stream, writeStream); //寫入並銷燬當前流 (egg demo提供的)
files.push({
[fieldname]: target //es6裏面的屬性名錶達式
});
}
this.ctx.body = {
files: files,
fields: parts.field // 全部表單字段都能經過 `parts.fields` 放在while循環後面
};
}
效果
![clipboard.png clipboard.png](http://static.javashuo.com/static/loading.gif)
![clipboard.png clipboard.png](http://static.javashuo.com/static/loading.gif)
![clipboard.png clipboard.png](http://static.javashuo.com/static/loading.gif)