آپلود فایل با React و Node — راهنمای گام به گام
آپلود فایل کار کاملاً سادهای است؛ اما کاربرد زیادی در هر اپلیکیشن یا وبسایت دارد. این عملیات شامل تحویل فایل و کپی کردن آن به یک مکان ریموت است.
فرایند آپلود فایل دو مؤلفه دارد:
- فرانتاند: به کاربر امکان انتخاب فایل را میدهد.
- بکاند (API): بخشی است که فرانتاند میتواند فایل را به آن ارسال کند.
اگر از یک سرویس مانند Amazon یا Firebase برای ذخیره فایلها استفاده میکنید، میتوانید یک نقطه انتهایی API برای ارسال فایل داشته باشید. در این حالت سرور با تنظیمات سادهای میتواند اقدام به ذخیرهسازی، فشردهسازی و تهیه نسخه پشتیبان از فایل و همچنین هر کار دیگری که مورد نیاز باشد بکند.
از آنجا که ما یک API موجود نداریم، یک API محلی با استفاده از Node ایجاد میکنیم و سپس از فرانتاند به آن API درخواست میدهیم.
ایجاد بکاند
اگر از قبل یک سرور با نقطه انتهایی دارید که درخواست ارسال فایل را به آن بفرستید، میتوانید از این بخش رد شده و به قسمت React یعنی فرانتاند مراجعه کنید. کد API بکاند را میتوانید در این صفحه گیتهاب (+) مشاهده کنید. این کد به صورت پیشفرض روی پورت 8000 کار میکند. نقطه انتهایی برای آپلود به صورت upload/ است.
در این راهنما از express-generator برای ایجاد یک سرور مقدماتی Express استفاده کردهایم. اگر express-generator را ندارید میتوانید آن را با دستور زیر نصب کنید:
npm install express-generator –global
سپس یک اپلیکیشن اکسپرس را با دستور زیر ایجاد میکنیم:
express-generator file-upload-api
اپلیکیشن بکاند را به صورت file-upload-api نامگذاری میکنیم. دستور فوق یک پوشه با اکسپرس ایجاد میکند؛ اما node_modules را نصب نمیکند.
cd file-upload-api npm install
دستورهای فوق دایرکتوری node_modules را ایجاد کرده و همه ماژولها را از package.json نصب میکنند.
آپلود فایل نیازمند بستههای بیشتر است:
npm install cors express-fileupload
به منظور دسترسی به بکاند از سرور دیگر که روی پورت متفاوت یا سرور دیگری اجرا میشود میتوانید از cors استفاده کنید.
express-file-upload نیز یک بسته کارآمد است که به مدیریت فایلهای آپلود شده در اکسپرس میپردازد. ما از یک میانافزار به همراه اکسپرس استفاده میکنیم تا فایلها را از دیسک محلی به سرور منتقل کنیم.
در ادامه سرور اکسپرس را طوری راهاندازی میکنیم که روی درخواست post به مسیر upload/ فعال شود. ما هیچ چیز غیرضروری را از بسته express-generator تغییر ندادهایم، چون تنها چیزی که برای مدیریت درخواستها لازم داریم یک سرور ابتدایی است.
1app.post('/upload', (req, res, next) => {
2 let uploadFile = req.files.file
3 const fileName = req.files.file.name
4 uploadFile.mv(
5 `${__dirname}/public/files/${fileName}`,
6 function (err) {
7 if (err) {
8 return res.status(500).send(err)
9 }
10
11 res.json({
12 file: `public/${req.files.file.name}`,
13 })
14 },
15 )
16})
وقتی که درخواست POST به مسیر upload/ برسد، فایل به مسیر public/files/fileName.ext/ کپی میشود. از آنجا که میخواهیم فایلی را ارسال کنیم که به کلید فایل در فرانتاند الحاق شده است، این فایل در مسیر req.files.file قابل دسترس خواهد بود. نام فایل نیز به صورت req.files.file.name قابل دسترسی است. اگر به جزئیات بیشتری در این خصوص نیاز دارد به مستندات این بسته (+) مراجعه کنید.
ایجاد فرانتاند روی React
اینک که نقطه انتهایی API خود را داریم تا فایل را به آن ارسال کنیم، میتوانیم روی اینترفیسی کار کنیم که به کاربر امکان آپلود فایل به سرور را میدهد. این کد را میتوانید در این ریپوی گیتهاب (+) ملاحظه کنید.
همانند همیشه کار خود را با دستور زیر آغاز میکنیم:
create-react-app
اگر این بسته را ندارید میتوانید آن را با npm نصب کنید:
create-react-app file-upload-react
ما باید یک فیلد آپلود فایل داشته باشیم که یک نوع ورودی است:
<input type="file"/>
مدیریت فایلهای منتخب
فرایند آپلود کردن فایل به یک نقشه نیاز دارد. چندین روش مختلف برای مدیریت آن وجود دارد. ما از روش زیر استفاده میکنیم:
- فایل را بگیرید. فایل در ورودی در [event.target.files[0 قرار دارد.
- حالت انتخاب فایل را با استفاده از onClick روی ورودی تعیین کنید.
- حالت دیگری به صورت loaded با مقدار 0 تعیین کنید. از این حالت برای نمایش فرایند پیشرفت آپلود فایل استفاده میکنیم.
- درخواست API را با کلیک شدن دکمه با استفاده از رویداد onClick در دکمه ارسال کنید.
این امکان وجود دارد که فایل را زمانی که تغییراتی در فایل ایجاد میشود ارسال کنید؛ اما ایده خوبی نیست. از آنجا که دکمه و فایل منتخب به صورت عملی با خود فایل سر و کار دارند، بهتر است از حالت (state) برای مدیریت فایل استفاده کنیم.
مقداردهی حالت
1this.state = { selectedFile: null, loaded: 0, }
دستگیرههای onClick را به App اضافه کنید تا انتخاب شدن فایل و تحویل فایل را اعلام کنند.
1return (
2 <div className="App">
3 <input type="file" name="" id="" onChange={this.handleselectedFile} />
4 <button onClick={this.handleUpload}>Upload</button>
5 <div> {Math.round(this.state.loaded,2) } %</div>
6 </div>
7 )
- handleSelectedFile به تعیین حالت برای فایل انتخاب شده و ریست کردن مقدار درصد آپلود میپردازد.
- handleUpload فایل را به محض کلیک کردن روی دکمه Upload به سرور ارسال میکند.
handleSelectedFile تنها به تعیین حالت selectedFile برابر با فایل منتخب میپردازد.
1handleselectedFile = event => {
2 this.setState({
3 selectedFile: event.target.files[0],
4 loaded: 0,
5 })
6 }
handleUpload فایل را به API آپلود خواهد کرد. به این منظور از کتابخانه سبک axios استفاده میکنیم.
npm install axios. import axios from 'axios'
یک درخواست POST با سه مؤلفه ارسال میکنیم که شامل نقطه انتهایی، فایل و آرگومان شیء دیگری برای نمایش پیشرفت است.
1handleUpload = () => {
2 const data = new FormData()
3 data.append('file', this.state.selectedFile, this.state.selectedFile.name)
4
5 axios
6 .post(endpoint, data, {
7 onUploadProgress: ProgressEvent => {
8 this.setState({
9 loaded: (ProgressEvent.loaded / ProgressEvent.total*100),
10 })
11 },
12 })
13 .then(res => {
14 console.log(res.statusText)
15 })
16
17 }
- یک FormData جدید به نام data ایجاد میکنیم. این یک شیء پیشفرض جاوا اسکریپت است. فیلد داده را با فایل و نام آن تکمیل میکنیم.
- یک endpoint در ابتدای فایل به صورت http://localhost:8000 تعریف کردهایم. data فایل الحاق شده است که باید ارسال شود.
- سومین آرگومان، گزارشدهی فرایند پیشرفت کار است و progressEvent را درخواست میکند. برای کسب اطلاعات بیشتر در این خصوص به این لینک (+) مراجعه کنید.
- progressEvent دارای مقادیر loaded و total است. ما از آنها برای محاسبه درصد و نمایش آن در div زیر دکمه استفاده میکنیم.
- وضعیت پاسخ پس از این که promise تحلیل شد گزارش میشود.
مشکلات و بهینهسازیها
آپلود کردن فایل با استفاده از React و Node هیچ مشکل خاصی ندارد؛ اما دموی ما مشکلاتی دارد. از آنجا که این فقط یک دموی ساده است، خطاها به درستی مدیریت نشدهاند. هیچ روشی برای لغو آپلود وجود ندارد. اگر فرانتاند را زمانی که فایل در حال آپلود است رفرش کنید، سرور از کار میافتد. همچنین سرور ما فایلهای اسکریپت را بررسی و یا کدهای آلوده را فیلتر نمیکند. با این جود به عنوان یک دمو قابل قبول است.
بدین ترتیب به پایان این راهنما با موضوع توضیح روش مدیریت آپلود فایلها در ریاکت با استفاده از Node به عنوان بکاند میرسیم. شما میتوانید از ریاکت برای آپلود فایل به API سرور ریموت و یا دیگر روشهای ذخیرهسازی داده نیز استفاده کنید.
اگر این نوشته برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای طراحی و توسعه پروژههای وب
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- مجموعه آموزشهای برنامه نویسی
- راهنمای جامع React (بخش اول) — از صفر تا صد
- آموزش React.js در کمتر از ۵ دقیقه — از صفر تا صد
- ری اکت (React) — راهنمای جامع برای شروع به کار
==