ทำระบบอัพโหลดไฟล์ด้วย Node.js + Multer
วิธีการทำระบบไฟล์อัพโหลดด้วยการใช้ Node.js + Express และ Multer ซึ่งบทความนี้เป็นบทความอัพเดท จากที่เคยเขียนไว้ก่อนหน้านี้ 7-8 แล้วครับ ทำระบบอัพโหลดไฟล์ด้วย Node.js ซึ่งตัว Library มันก็มีการอัพเดทไปพอสมควร
Step 1 - Create Project
เริ่มต้นด้วยการสร้างโปรเจ็คขึ้นมาโดยใช้ npm init
หรือ yarn init
ก็ได้
จากนั้นก็ทำการติดตั้ง express และ multer
Step 2 - Frontend (index.html)
ต่อมาสร้างไฟล์ index.html
ขึ้นมา โดยส่วนนี้จะเป็นหน้าเว็บธรรมดา ที่มีแค่การอัพโหลดไฟล์ โดยใช้ <input type="file" />
โดยที่ตัว form ต้องกำหนด enctype
เป็น multipart/form-data
Step 3 - Create Server
สร้าง app.js
ขึ้นมา เพื่อเป็น Server ง่ายๆ โดยให้ index ทำการอ่านจากไฟล์ index.html
ที่เราสร้างไว้้ และ POST /upload
เพื่อไว้รับค่า จากไฟล์ที่เราต้องการอัพโหลด
ทดสอบ โดยการ start server
ทดสอบเรียก request ไปที่ POST /upload
เพื่อดูผลลัพธ์
หรือทดสอบด้วย Postman
จะเห็นว่าเราจะไม่ได้ผลลัพธ์อะไร แม้ว่าเราจะให้มัน res.json(req.body)
ก็ตาม เพราะเนื่องจาก โดย default ตัว Express ไม่สามารถอ่าน req.body
ได้ ถ้าอยากให้อ่านได้ คือใช้ body-parser หรือใช้ตัว express.json()
แบบนี้
Restart และทดสอบ POST Request ไปใหม่ จะเห็นว่าเราสามารถอ่านค่า req.body
ได้แล้ว
Step 4- Multer
ตัว multer จะมาช่วยจัดการเรื่องของไฟล์ โดยที่เราจะสามารถเข้าถึง object ไฟล์ client ส่งมา ด้วย req.file
และตัว req.body
ตัว multer ก็ทำการ handle ให้เราแล้ว ฉะนั้น ก็ไม่จำเป็นต้องใช้ body-parser เราก็สามารถเข้าถึงได้ทั้ง req.file
และ req.body
โค๊ดด้านบนเป็นการกำหนด multer และให้โฟลเดอร์ที่เราจะเก็บไฟล์คือ uploads
สิ่งที่ต้องรู้คือ
upload.single
: จะอัพโหลดได้ทีละไฟล์- ตัว
upload.single('photo')
ชื่อที่เรากำหนด ต้องเป็นชื่อเดียวกับ form ของเรา<input name="photo" />
ทดลองเปิดหน้าเว็บ http://localhost:9999 จากนั้นเลือกไฟล์แล้วคลิ๊ก Upload ดูครับ จะได้ผลลัพธ์ประมาณนี้
จะเห็นได้ว่า ไฟล์ที่เราอัพโหลด เราสามารถรู้ค่า properties ได้ อย่างเช่น
originalname
: ชื่อไฟล์ที่เราอัพโหลดfilename
: ชื่อไฟล์หลังจากที่อัพโหลดmimetype
: ชนิดของไฟล์path
: location ที่เก็บไฟล์หลักจากถูกอัพโหลดsize
: ขนาดของไฟล์
Step 5 - Customize Multer
ต่อมาเรามาปรับแต่ง Multer เพิ่มเติม เนื่องจากตัว default แค่กำหนด folder เท่านั้น ยังไม่ได้ตั้งชื่อไฟล์เลย โดยเราจะใช้ DiskStorage
และกำหนด options ด้วย destination
และ filename
แบบนี้
destination
- เป็นการบอกว่าให้อัพโหลดไปที่โฟลเดอร์ไหน (เราต้องสร้างโฟลเดอร์เองนะครับ)filename
- function ที่ให้เรากำหนดชื่อไฟล์ได้ โดย return เป็น callback กลับไป ตัวอย่างผมใช้file.originalname
ครับ
กำหนดขนาดไฟล์
เราสามารถกำหนดขนาดไฟล์ด้วยการใช้ limits
เช่น กำหนดให้ไฟล์มีขนาดไม่เกิน 1000 (bytes)
ทดลองอัพโหลไฟล์ใหม่ จะได้ error (เนื่องจากเรากำหนดขนาดแค่ 1000 bytes หรือ ~1kb เอง)
เปลี่ยนใหม่ ให้เป็น use case จริงๆ เช่น ไฟล์ไม่เกิน 1MB (1M ถ้านับแบบ decimal ก็ 1ล้าน ถ้านับแบบ binary ก็คือ 1024x1024)
รองรับการอัพโหลดหลายๆไฟล์
เราจะใช้ upload.array('images')
เพื่อทำการอัพโหลดหลายๆไฟล์ครับ และเข้าถึงด้วย req.files
เช่น
โดยที่ฝั่ง Client (HTML) ก็แค่เพิ่ม attribute multiple
ลงไปแบบนี้
ตัว index.html
แบบที่รองรับทั้ง ไฟล์เดียว และหลายไฟล์
อื่นๆ
นอกจากนี้ ทางฝั่ง Client เรายังสามารถใช้ FormData เพื่อทำการสร้าง multipart/form-data
ด้วย key value ได้อีกด้วย ประมาณนี้
เดี๋ยวบทความถัดๆไป จะมีตัวอย่างการทำ File Upload ฝั่ง Client ออกมานะครับ เช่น ใช้ Vanilla JavaScript ธรรมดาๆ ร่วมกับ FileReader API กับ FormData หรือ React.js หรือ Dropzone, Uppy, FilePond เป็นต้นครับ
ปัญหาอื่นๆ
เกิดขึ้น กรณีที่เรากำหนด .single('file')
หรือ .array('files')
และชื่อไม่ตรง input
ไฟล์มีขนาดใหญ่เกิดกว่าที่เรากำหนด
ไม่มีโฟลเดอร์ที่เรากำหนดให้ multer อัพโหลด (ให้เราสร้างโฟลเดอร์เอง) นอกจากใช้ multer({ dest: 'uploads'})
multer ถึงจะสร้าง folder ให้เราอัตโนมัติ
สรุป
ตัวอย่างนี้ก็เป็นตัวอย่างง่ายๆ ในการทำระบบอัพโหลดไฟล์ด้วย Node.js นะครับ ตัว multer ก็สามารถรองรับทั้งอัพโหลดทีละไฟล์ อัพโหลดหลายๆไฟล์ รวมถึงเรายังสามารถต่อยอด ไปใช้การเก็บข้อมูลลง AWS S3 ได้อีกด้วย ก็หวังว่าบทความนี้จะเป็นประโยชน์ไม่มากก็น้อย ลองเล่น ลองฝึกและลงมือทำกันดูนะครับ
Happy Coding ❤️
- Authors
-
Chai Phonbopit
เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust