สามารถดู video ของหัวข้อนี้ก่อนได้ ดู video
Upload คืออะไร ?
Upload คือการนำไฟล์จากเครื่องต้นทาง ส่งไฟล์ไปยังเครื่องปลายทาง ซึ่งเครื่องปลายทางจะเป็นอะไรก็ได้ เช่น
- เครื่อง server เครื่องนั้น
- Cloud server
เคสที่เราจะมาลองทำกัน
upload ลงเครื่องเราเอง (จากเครื่องเราเอง) โดยเราจะมีการแยกตาม topic ต่างๆไปตั้งแต่
- upload แบบปกติ
- ทำ progress upload
- validate file หรือขนาดที่ต้องการ
- cancel upload
Structure
โดย package.json จะมี package เป็นตามนี้
โดย package ที่เราจะลงจะประกอบด้วย
express
สำหรับทำ API
cors
สำหรับเปิด Cross origin ให้สามารถยิง API ผ่าน Frontend ได้
multer
สำหรับ upload file เข้าเครื่อง
จริงๆ Express มีการแนะนำเรื่องการใช้ multer upload อยู่แล้วที่นี่
https://expressjs.com/en/resources/middleware/multer.html
เริ่มทำ API Upload และ upload แบบปกติ
สิ่งที่เราจะทำ
- เพิ่ม API สำหรับการ upload file เข้ามา (โดยลง multer ไป)
- (ฝั่ง Frontend) upload file ผ่าน form data เข้าไปผ่าน axios
ใช้ Form data เพราะเป็น Web API ที่ support ทั้ง Browser (ส่งไฟล์) และ Server (รับไฟล์) รวมถึง support การส่งหลายไฟล์ด้วย
ที่ Backend index.js
ที่ Frontend src/index.html
ทำ progress การ upload
- ตัว multer ได้มีการทำเรื่องการส่ง progress มาอยู่แล้ว = ฝั่ง Backend ไม่ต้องปรับอะไร
- ฝั่ง Frontend ใช้
onUploadProgress
ของ axios
ในการแสดง progress ได้เลย
ผลลัพธ์จะได้ออกมาเป็นประมาณนี้
validate file เฉพาะ ไฟล์ที่ต้องการ
ดัก file type
สมมุติเราต้องการไฟล์แค่ file type mp4
เท่านั้น ปกติ สามารถดักได้ 2 ทาง
- ดักจาก Frontend = ก่อนส่งไปยัง API upload เช็คก่อนว่า file type ถูกหรือไม่ ?
- ดักจาก Backend = ก่อน upload จริง เช็คก่อนว่า file type ถูกหรือไม่ ?
ท่าดักจาก frontend
ท่าดักจาก backend
- เพิ่ม fileFilter เข้า multer เข้าไปเพื่อเป็นตัวกั้นก่อน
- ย้าย upload.single จากเป็น middleware ให้มาเรียกเป็น function แทน เพื่อให้สามารถ handle error เป็น json ออกมาได้ (จัดการผ่าน callback)
ผลลัพธ์ของเรื่องราวนี้
ดัก file size
- ดักจาก Frontend = เช็คขนาด size ก่อน (ในหน่วย byte) ถ้าขนาดเกิน = ไม่ยิง API upload
- ดักจาก Backend = ก่อน upload จริง เช็คก่อนว่า file size ถูกต้องหรือไม่
ท่าดักจาก Frontend
- เพิ่มการเช็คขนาด file ด้วย
fileInput.files[0].size
(ไอเดียคล้ายๆเช็ค type)
ท่าดักจาก Backend
- เพิ่มการเช็คขนาดด้วย limit (option ของ multer) สามารถทำได้เลย
cancel การ upload
เมื่อมีการปิด browser ระหว่างกลางหรือมีการกด cancel = ควรจะลบไฟล์ออก (แปลว่า Request นั้นโดน reject ทิ้ง)
- ฝั่ง Frontend ต้องทำการตัด Request API ทิ้งเมื่อมีการ cancel
- ฝั่ง Backend ต้องทำการจัดการ file ทิ้งเมื่อเจอว่า Request โดน reject ระหว่างทาง (abort)
ฝั่ง Frontend
ฝั่ง Backend เพิ่ม code ที่ req ตรง filename เพื่อให้สามารถดึง path มาลบภาพได้
ผลลัพธ์
อื่นๆ ที่ยังมีเกี่ยวกับ upload
- upload หลาย file ต้องปรับให้รับเป็น multiple แทน
ปรับ Frontend ให้รับแบบ multiple
และฝั่ง Backend ให้รับเป็น array แทน
- stream upload (หั่นค่อยๆ upload ไป) เดี๋ยวผมจะขอเก็บไว้เล่าเรื่องของ stream upload อีกที ผมอยากซาวเสียงนิดนึงว่าสนใจกันไหม หรือสนใจเรื่องอื่นกัน
- continue upload
- การ upload ผ่าน cloud (ผมจะเก็บไปแสดงวิธีทำในหัวข้อ Firebase cloud firestore ของ Vue firebase masterclass)
Github
https://github.com/mikelopster/upload-basic