Nodejs文件上傳、監(jiān)聽上傳進(jìn)度的代碼
前言
文件上傳如果加上進(jìn)度條會(huì)有更好的用戶體驗(yàn)(尤其是中大型文件),本文使用 Nodejs 配合前端完成這個(gè)功能。
前端我們使用 FormData 來作為載體發(fā)送數(shù)據(jù)。
效果
前端部分
HTML 部分 和 Js 部分
<input type="file" id="file" />
<!-- 進(jìn)度條 -->
<progress id="progress" value="0" max="100"></progress>
// 獲取 input file 的 dom 對象
const inputFile = document.querySelector('#file');
// 監(jiān)聽 change 事件
inputFile.addEventListener('change', function() {
// 使用 formData 裝載 file
const formData = new FormData();
formData.append('file', this.files[0]);
// 上傳文件
upload(formData);
})
下面我們實(shí)現(xiàn) upload 方法。
使用 XMLHttpRequest 的方式
const upload = ( formData ) => {
const xhr = new XMLHttpRequest();
// 監(jiān)聽文件上傳進(jìn)度
xhr.upload.addEventListener('progress', function(e) {
if (e.lengthComputable) {
// 獲取進(jìn)度
const progress = Math.round((e.loaded * 100) / e.total);
document.querySelector('#progress').setAttribute('value', progress);
}
},false);
// 監(jiān)聽上傳完成事件
xhr.addEventListener('load', ()=>{
console.log(':smile:上傳完成')
}, false);
xhr.open('post', 'http://127.0.0.1:3000/upload');
xhr.send(formData);
}
使用 jQuery 的 ajax 上傳
jQuery 目前的使用量依然龐大,那么使用 jQuery 的 ajax 如何監(jiān)聽文件上傳進(jìn)度呢:
const upload = ( formData ) => {
$.ajax({
type: 'post',
url: 'http://127.0.0.1:3000/upload',
data: formData,
// 不進(jìn)行數(shù)據(jù)處理和內(nèi)容處理
processData: false,
contentType: false,
// 監(jiān)聽 xhr
xhr: function() {
const xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener('progress', e => {
const { loaded, total } = e;
var progress = (loaded / total) * 100;
document.querySelector('#progress').setAttribute('value', progress);
},
false
);
return xhr;
}
},
success: function(response) {
console.log('上傳成功');
}
});
}
使用 axios 上傳并監(jiān)聽進(jìn)度
axios 使用量非常大,用它監(jiān)聽文件上傳更簡單,代碼如下:
const upload = async ( formData ) => {
let config = {
// 注意要把 contentType 設(shè)置為 multipart/form-data
headers: {
'Content-Type': 'multipart/form-data'
},
// 監(jiān)聽 onUploadProgress 事件
onUploadProgress: e => {
const {loaded, total} = e;
// 使用本地 progress 事件
if (e.lengthComputable) {
let progress = loaded / total * 100;
document.querySelector('#progress').setAttribute('value', progress);
}
}
};
const { status } = await axios.post('http://127.0.0.1:3000/upload', formData, config);
if (res.status === 200) {
console.log('上傳完成:grinning:');
}
}
Nodejs 部分
這部分比較簡單,其實(shí)就是單純的文件上傳,我們用 Koa 來實(shí)現(xiàn).
環(huán)境搭建及依賴包安裝
這里使用 koa2 ,安裝以下依賴包:
- koa
- @koa/router: koa 的路由
- @koa/cors:用于跨域
- koa-body: 解析 body 數(shù)據(jù)
- nodemon: 使用它啟動(dòng)服務(wù),帶有熱更新
代碼部分
const Koa = require('koa');
const Router = require('@koa/router');
const koaBody = require('koa-body');
const path = require('path');
const fs = require('fs');
const cors = require('@koa/cors');
const app = new Koa();
const router = new Router();
router.all('/upload', async ctx => {
// 處理文件上傳
const res = await dealFile(ctx);
res && (ctx.body = {
status: 200,
msg: 'complete'
});
});
// 中間件部分
app.use(cors());
app.use(
koaBody({
multipart: true,
formidable: {
maxFileSize: 2000 * 1024 * 1024 //最大2G
}
})
);
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3000);
dealFile 方法處理上傳的文件
出于性能考慮,操作 file 毫無疑問要使用 stream 。
我們要監(jiān)聽文件流 end 事件,由于無法在事件回調(diào)里返回響應(yīng),因?yàn)闀?huì)報(bào) 404,所以需要使用 Promise 來封裝一下,然后用 async、await
const dealFile = ctx => {
const { file } = ctx.request.files;
const reader = fs.createReadStream(file.path);
const writer = fs.createWriteStream(
// 文件上傳到 image 文件夾中
path.resolve(__dirname, './image', file.name)
);
return new Promise((resove, reject) => {
reader.pipe(writer);
reader.on('end', () => {
resove(true);
});
reader.on('error', err => {
throw err;
})
});
};
到這里就全部完成了。
這里注意一下:前端監(jiān)聽文件進(jìn)度不需要后端有什么特殊處理,后端僅僅是做了文件流的寫入而已。
總結(jié)
到此這篇關(guān)于Nodejs文件上傳、監(jiān)聽上傳進(jìn)度的文章就介紹到這了,更多相關(guān)Nodejs文件上傳、監(jiān)聽上傳進(jìn)度內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JS實(shí)現(xiàn)批量上傳文件并顯示進(jìn)度功能
- JS插件plupload.js實(shí)現(xiàn)多圖上傳并顯示進(jìn)度條
- js實(shí)現(xiàn)帶進(jìn)度條提示的多視頻上傳功能
- JS實(shí)現(xiàn)上傳文件顯示進(jìn)度條
- JS+html5實(shí)現(xiàn)異步上傳圖片顯示上傳文件進(jìn)度條功能示例
- 基于JS實(shí)現(xiàn)視頻上傳顯示進(jìn)度條
- 原生javascript上傳圖片帶進(jìn)度條【實(shí)例分享】
- 教你3分鐘利用原生js實(shí)現(xiàn)有進(jìn)度監(jiān)聽的文件上傳預(yù)覽組件
- Node.js上傳文件功能之服務(wù)端如何獲取文件上傳進(jìn)度
- JavaScript實(shí)現(xiàn)監(jiān)控上傳和下載進(jìn)度
- JavaScript獲取上傳進(jìn)度的幾種方式實(shí)現(xiàn)
相關(guān)文章
如何從頭實(shí)現(xiàn)一個(gè)node.js的koa框架
這篇文章主要介紹了如何從頭實(shí)現(xiàn)一個(gè)node.js的koa框架,koa.js是最流行的node.js后端框架之一,有很多網(wǎng)站都使用koa進(jìn)行開發(fā),同時(shí)社區(qū)也涌現(xiàn)出了一大批基于koa封裝的企業(yè)級(jí)框架。,需要的朋友可以參考下2019-06-06
node+multer實(shí)現(xiàn)圖片上傳的示例代碼
這篇文章主要介紹了node+multer實(shí)現(xiàn)圖片上傳的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02
詳解如何在NodeJS項(xiàng)目中優(yōu)雅的使用ES6
本篇文章主要介紹了詳解如何在NodeJS項(xiàng)目中優(yōu)雅的使用ES6,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04
NodeJS實(shí)現(xiàn)單點(diǎn)登錄原理解析
隨著公司業(yè)務(wù)的增多,必然會(huì)產(chǎn)生各個(gè)不同的系統(tǒng),如果每個(gè)系統(tǒng)都需要單獨(dú)登錄的話就會(huì)很不方便,所以這個(gè)時(shí)候單點(diǎn)登錄會(huì)很方便,今天通過本文給大家講解NodeJS實(shí)現(xiàn)單點(diǎn)登錄原理解析,感興趣的朋友一起看看吧2022-05-05
基于Nodejs實(shí)現(xiàn)文件壓縮和解壓功能
在?windows?系統(tǒng)上面,我們壓縮文件,常常需要安裝一些壓縮軟件才能實(shí)現(xiàn)壓縮,可能有些還存在一些問題,所以本文就來使用Nodejs實(shí)現(xiàn)文件壓縮和解壓功能吧2024-03-03
如何在 Node.js 中使用 axios 配置代理并實(shí)現(xiàn)圖片并發(fā)下載
這篇文章主要介紹了如何在Node.js中使用axios配置代理并實(shí)現(xiàn)圖片并發(fā)下載,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-07-07
node.js程序作為服務(wù)并在windows下開機(jī)自啟動(dòng)(用forever)
這篇文章主要介紹了node.js程序作為服務(wù)并在windows下開機(jī)自啟動(dòng)的相關(guān)資料,因?yàn)閷?shí)現(xiàn)的功能比較簡單,沒有選擇功能比較強(qiáng)大的pm2,文中選擇利用了forever,需要的朋友可以參考借鑒,下面來一起看看吧。2017-03-03

