Devahoy Logo
PublishedAt

NodeJS

ทำระบบอัพโหลดไฟล์ด้วย Node.js

ทำระบบอัพโหลดไฟล์ด้วย Node.js

บทความนี้จะพูดถึงตัวอย่างการทำไฟล์อัพโหลดด้วยการใช้ Node.js + Express.js ร่วมกับ Middleware ของ Express.js ด้วย Multer สำหรับบทความนี้จะมีเทคโนโลยีที่เกี่ยวข้องดังนี้

Step 1 : Create Project

เริ่มต้นทำการสร้างโฟลเดอร์ขึ้นมาใหม่ จากนั้นสร้างไฟล์ package.json ขึ้นมา (หรือจะใช้คำสั่ง npm init ก็ได้)

1
mkdir file-upload
2
cd file-upload
3
touch package.json

ที่ไฟล์ package.json ตั้งชื่อโปรเจ็คและกำหนดเวอร์ชัน ผมกำหนดไว้แบบนี้

Terminal window
{
"name": "file-upload",
"version": "0.0.1"
}

ต่อมาติดตั้ง dependencies ที่จะใช้ คือ express และ multer

1
npm install express multer --save-dev

ไฟล์ package.json หลังจากที่ติดตั้ง dependencies เรียบร้อยแล้วจะได้ดังนี้

Terminal window
{
"name": "file-upload",
"version": "0.0.1",
"devDependencies": {
"express": "^4.12.3",
"multer": "^0.1.8"
}
}

Step 2 : index.html

ต่อมาทำการสร้างไฟล์ index.html ขึ้นมา ในส่วนนี้จะไม่ใช้ Template Engine เช่น Jade นะครับ เพราะว่าเป็นแค่ไฟล์อัพโหลดธรรมดา หน้าตา index.html ก็มีแค่นี้เอง

1
<!doctype html>
2
<html>
3
<head>
4
<meta charset="UTF-8" />
5
<title>Sample File Upload</title>
6
</head>
7
<body>
8
<form action="/upload" method="post" enctype="multipart/form-data">
9
<input type="file" name="file" />
10
<input type="submit" value="Upload" />
11
</form>
12
</body>
13
</html>

กำหนด form ไปที่ /upload แบบ POST และกำหนดเป็น enctype="multipart/form-data" โดยในส่วนไฟล์อัพโหลด เราจะใช้ input เป็นแบบ file

Step 3 : server.js

ต่อมาในส่วน server.js ทำการเขียนโค๊ดเพื่อกำหนด route และรับ request & response ด้วย express.js แบบนี้

1
var express = require('express')
2
var app = express()
3
4
app.get('/', function (req, res) {
5
res.sendFile(__dirname + '/index.html')
6
})
7
8
app.post('/upload', function (req, res) {
9
res.send(req.files)
10
})
11
12
app.listen(5555, function () {
13
console.log('App running on port 5555')
14
})

ทดสอบรันเซิฟเวอร์ดู

1
node server.js

จากนั้นเข้าเว็บ http://localhost:5555 และทำการอัพโหลดไฟล์หรือรูปภาพดู สังเกตผลลัพธ์

จะเห็นว่า ยังไม่มี result อะไรออกมา เนื่องจากตัว Express.js โดย default แล้ว มัน handle เฉพาะ urlencoded และ JSON ไม่รวม multipart ฉะนั้นต้องใช้ middleware อย่าง multer มาช่วย

Step 4 : Use multer

ที่ไฟล์ server.js ทำการ require multer เข้ามา จากนั้นเพิ่มโค๊ด

1
app.use(multer());

server.js จะได้เป็นแบบนี้

1
var express = require('express')
2
var multer = require('multer')
3
4
var app = express()
5
app.use(multer())
6
7
app.get('/', function (req, res) {
8
res.sendFile(__dirname + '/index.html')
9
})
10
11
app.post('/upload', function (req, res) {
12
res.send(req.files)
13
})
14
15
app.listen(5555, function () {
16
console.log('App running on port 5555')
17
})

จากนั้นทำการ restart server อีกครั้ง ทดสอบอัพโหลดไฟล์ กด Upload ก็จะเห็นผลลัพธ์แสดงเป็นไฟล์ JSON แบบนี้

1
{
2
"file": {
3
"fieldname": "file",
4
"originalname": "sample.png",
5
"name": "02d6a43b22b6cd220336bc35d4e93c6b.png",
6
"encoding": "7bit",
7
"mimetype": "image/png",
8
"path": "/tmp/02d6a43b22b6cd220336bc35d4e93c6b.png",
9
"extension": "png",
10
"size": 3947,
11
"truncated": false,
12
"buffer": null
13
}
14
}

จะเห็นได้ว่า ไฟล์ที่เราอัพโหลด เราสามารถรู้ค่า properties ได้ อย่างเช่น

  • originalname : ชื่อไฟล์ที่เราอัพโหลด
  • name : ชื่อไฟล์หลังจากที่อัพโหลด
  • mimetype : ชนิดของไฟล์
  • path : location ที่เก็บไฟล์หลักจากถูกอัพโหลด (default น่าจะถูกเก็บไว้ที่ temp)
  • extension : นามสกุลไฟล์

ที่นี้เราจะทำอะไรกับไฟล์ที่อัพโหลดก็สามารถทำได้

ถ้าเป็นระบบจริงๆ เมื่อทำการอัพโหลดไฟล์ควรจะกำหนดสิทธิ์ หรือลบออกจาก file system ไม่เช่นนั้น server คุณอาจจะถูก bomb จากการอัพโหลดไฟล์เข้ามาจนเซิฟเวอร์ล่มได้ :)

Step 5 : Multer Configuration

สุดท้าย เราสามารถที่จะกำหนดค่า multer ต่างๆได้ เช่น

  • เปลี่ยนชื่อไฟล์ที่อัพโหลด โดย generate ตาม timestamp
  • กำหนด path ที่เก็บไฟล์ เช่น ไว้ที่โฟลเดอร์ /uploads
  • จำกัดขนาดไฟล์ให้ไม่เกิน 1 MB

ที่ไฟล์ server.js ตรงส่วน app.use(multer()); เราสามารถส่ง object ที่ใช้กำหนดค่าได้แบบนี้

1
var fs = require('fs')
2
3
app.use(
4
multer({
5
dest: __dirname + '/uploads/',
6
rename: function (fieldname, filename) {
7
return Date.now()
8
},
9
limits: {
10
fileSize: 100000
11
},
12
onFileSizeLimit: function (file) {
13
console.log('Failed: ' + file.originalname + ' is limited')
14
fs.unlink(file.path)
15
}
16
})
17
)
  • dest : ไว้กำหนด location ที่เก็บไฟล์
  • rename : เปลี่ยนชื่อไฟล์ที่อัพโหลด
  • limits : ไว้กำหนด limit ต่างๆ เช่น ขนาดไฟล์ ความยาวชื่อไฟล์ เป็นต้น
  • onFileSizeLimit : ฟังค์ชันที่ทำงานเมื่อไฟล์เกินลิมิตที่กำหนด

ทีนี้เวลาอัพโหลดไฟล์ลงไปใหม่ path ที่เก็บไฟล์ ชื่อไฟล์ ก็จะถูกเปลี่ยนตามที่เรากำหนด options ไว้ครับ

สุดท้าย ไฟล์ server.js เป็นแบบนี้ครับ

1
var express = require('express')
2
var multer = require('multer')
3
var fs = require('fs')
4
5
var app = express()
6
7
app.use(
8
multer({
9
dest: __dirname + '/uploads/',
10
rename: function (fieldname, filename) {
11
return Date.now()
12
},
13
limits: {
14
fileSize: 100000
15
},
16
onFileSizeLimit: function (file) {
17
console.log('Failed: ' + file.originalname + ' is limited')
18
fs.unlink(file.path)
19
}
20
})
21
)
22
23
app.get('/', function (req, res) {
24
res.sendFile(__dirname + '/index.html')
25
})
26
27
app.post('/upload', function (req, res) {
28
res.send(req.files)
29
})
30
31
app.listen(5555, function () {
32
console.log('App running on port 5555')
33
})

สรุป

ตัวอย่างนี้ก็เป็นการทำไฟล์อัพโหลดแบบง่ายๆ ด้วยวิธีของผมเองนะครับ ไม่ชัวร์ว่าจะเป็น Best Practice หรือเปล่า ด้วย Node.js + Express.js + Multer เท่านั้นครับ หากมีตรงไหนผิดพลาด แนะนำเพิ่มเติมได้ครับ หรือหากต้องการรายละเอียดเพิ่มเติม ก็สามารถอ่านได้ที่ references

References

Authors
avatar

Chai Phonbopit

เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust

Related Posts