React和Node.js快速上傳進(jìn)度條功能實(shí)現(xiàn)
正文
在現(xiàn)代的Web應(yīng)用程序中,文件上傳是一個(gè)很常見(jiàn)的需求。上傳進(jìn)度條是一種用于告知用戶(hù)上傳進(jìn)度的工具,它可以讓用戶(hù)了解上傳進(jìn)度,以便他們可以知道何時(shí)可以繼續(xù)執(zhí)行其他任務(wù)。在本教程中,我們將學(xué)習(xí)如何使用React和Node.js實(shí)現(xiàn)上傳進(jìn)度條功能。
技術(shù)棧
- React: 一個(gè)流行的JavaScript庫(kù),用于構(gòu)建用戶(hù)界面。
- Node.js: 一個(gè)基于JavaScript運(yùn)行的開(kāi)放源代碼、跨平臺(tái)、輕量級(jí)的運(yùn)行時(shí)環(huán)境。
- Koa2: 一個(gè)基于Node.js平臺(tái)的Web開(kāi)發(fā)框架,提供了更簡(jiǎn)潔、更強(qiáng)大的API。
實(shí)現(xiàn)過(guò)程
1. 前端
import React, { useState } from 'react';
import axios from 'axios';
function UploadForm() {
const [selectedFile, setSelectedFile] = useState(null);
const [uploadProgress, setUploadProgress] = useState(0);
const [uploadedFile, setUploadedFile] = useState(null);
const handleFileSelect = (event) => {
setSelectedFile(event.target.files[0]);
};
const handleSubmit = async (event) => {
event.preventDefault();
const formData = new FormData();
formData.append('file', selectedFile);
const config = {
onUploadProgress: (progressEvent) => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
setUploadProgress(percentCompleted);
},
};
try {
const response = await axios.post('/api/upload', formData, config);
setUploadedFile(response.data.filename);
setSelectedFile(null);
setUploadProgress(0);
} catch (error) {
console.log(error);
}
};
const handleDownload = async () => {
try {
const response = await axios.get(`/api/download?filename=${uploadedFile}`, {
responseType: 'blob',
});
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', uploadedFile);
document.body.appendChild(link);
link.click();
} catch (error) {
console.log(error);
}
};
return (
<div>
<form onSubmit={handleSubmit}>
<input type="file" onChange={handleFileSelect} />
<button type="submit">Upload</button>
</form>
{selectedFile && (
<div>
Uploading {selectedFile.name}: {uploadProgress}%
</div>
)}
{uploadedFile && (
<div>
File uploaded: <a href="#" rel="external nofollow" onClick={handleDownload}>{uploadedFile}</a>
</div>
)}
</div>
);
}
export default UploadForm;
我們首先定義了一個(gè)UploadForm組件,它包含一個(gè)表單和一些狀態(tài)變量。當(dāng)用戶(hù)選擇文件時(shí),我們將文件保存在狀態(tài)中。當(dāng)用戶(hù)提交表單時(shí),我們將使用axios庫(kù)將文件上傳到服務(wù)器,并通過(guò)狀態(tài)變量跟蹤上傳進(jìn)度。如果上傳成功,我們將保存文件名并將狀態(tài)變量重置為初始值。
當(dāng)文件上傳成功后,我們會(huì)在頁(yè)面上顯示一個(gè)下載鏈接,當(dāng)用戶(hù)單擊該鏈接時(shí),我們將使用axios庫(kù)從服務(wù)器下載文件,并將其保存到用戶(hù)的計(jì)算機(jī)上。
2. 后端服務(wù)(server.js)
const Koa = require("koa");
const Router = require("koa-router");
const koaBody = require("koa-body");
const cors = require("@koa/cors");
const fs = require("fs");
const path = require("path");
const app = new Koa();
const router = new Router();
// 配置跨域
app.use(cors());
// 配置Koa Body中間件以處理文件上傳
app.use(
koaBody({
multipart: true,
formidable: {
uploadDir: path.join(__dirname, "uploads"),
keepExtensions: true,
},
})
);
// 上傳接口
router.post("/api/upload", async (ctx) => {
const file = ctx.request.files.file;
const filename = file.name;
const filepath = file.path || file.filepath;
// 計(jì)算文件大小
const fileSizeInBytes = fs.statSync(filepath).size;
const fileSizeInMegabytes = fileSizeInBytes / (1024 * 1024);
ctx.body = {
filename,
size: fileSizeInMegabytes.toFixed(2),
};
});
// 下載接口
router.get("/api/download", async (ctx) => {
const filename = ctx.query.filename;
const filepath = path.join(__dirname, "uploads", filename);
const fileStream = fs.createReadStream(filepath);
ctx.response.attachment(filename);
ctx.body = fileStream;
});
app.use(router.routes());
app.use(router.allowedMethods());
// 啟動(dòng)!
const port = process.env.PORT || 3001;
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});
我們首先引入所需的模塊,然后創(chuàng)建一個(gè)Koa實(shí)例,并將其與一個(gè)路由器實(shí)例連接。我們啟用CORS,以便從任何域都可以訪問(wèn)我們的API。
我們使用koa-body中間件來(lái)處理文件上傳。這個(gè)中間件會(huì)將文件存儲(chǔ)在本地文件系統(tǒng)中,并將文件元數(shù)據(jù)附加到請(qǐng)求對(duì)象上。
我們定義了兩個(gè)路由處理程序,一個(gè)用于處理文件上傳,另一個(gè)用于處理文件下載。在文件上傳處理程序中,我們從請(qǐng)求對(duì)象中獲取上傳的文件,并將文件名和大小發(fā)送回客戶(hù)端。在文件下載處理程序中,我們讀取文件并將其發(fā)送回客戶(hù)端。
我們最后將路由器連接到Koa應(yīng)用程序?qū)嵗⒃诙丝?001上啟動(dòng)服務(wù)器。
現(xiàn)在我們已經(jīng)完成了整個(gè)應(yīng)用程序的開(kāi)發(fā)。我們可以使用以下命令啟動(dòng)服務(wù)器和客戶(hù)端:
// 前端 npm run start //服務(wù)端 node server.js
這就是我們?nèi)绾问褂肦eact和Node.js實(shí)現(xiàn)文件上傳進(jìn)度條功能的全部過(guò)程。
以上就是React和Node.js快速上傳進(jìn)度條功能實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于React Node.js上傳進(jìn)度條的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
npm install -g 遇到權(quán)限問(wèn)題解析
這篇文章主要為大家介紹了npm install -g 遇到權(quán)限問(wèn)題解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
NodeJS落地WebSocket實(shí)踐前端架構(gòu)師破局技術(shù)
這篇文章主要為大家介紹了NodeJS落地WebSocket實(shí)踐前端架構(gòu)師破局技術(shù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
淺談Node.js ORM框架Sequlize之表間關(guān)系
下面小編就為大家?guī)?lái)一篇淺談Node.js ORM框架Sequlize之表間關(guān)系。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-07-07
使用Node.js創(chuàng)建HTTP服務(wù)器并實(shí)現(xiàn)公網(wǎng)訪問(wèn)本地Server的步驟
Node.js含有一系列內(nèi)置模塊,使得程序可以脫離 Apache HTTP Server 或 IIS,作為獨(dú)立服務(wù)器運(yùn),下面將介紹如何簡(jiǎn)單幾步實(shí)現(xiàn)遠(yuǎn)程公共網(wǎng)絡(luò)下訪問(wèn)windwos node.js的服務(wù)端,感興趣的朋友一起看看吧2023-11-11
利用node.js實(shí)現(xiàn)自動(dòng)生成前端項(xiàng)目組件的方法詳解
最近在學(xué)習(xí)用,基于nodejs的強(qiáng)大,我從原本的只寫(xiě)前端變成了寫(xiě)全棧。下面這篇文章主要給大家介紹了關(guān)于利用node.js實(shí)現(xiàn)自動(dòng)生成前端項(xiàng)目組件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面來(lái)一起看看吧。2017-07-07

