Upload File trong NodeJs


Khi một web client tải một tệp lên máy chủ, nó thường được gửi thông qua form và được mã hóa dưới dạng dữ liệu multipart/form-data. Multer là một middleware cho Express và Nodejs giúp dễ dàng xử lý dữ liệu multipart/form-data khi người dùng upload file.

Cài đặt

Sau khi cài đặt ứng dụng với express, ta tiến hành các package cần thiết

npm install multer body-parser --save

Tạo file app.js

// call all the required packages
const express = require('express')
const bodyParser= require('body-parser')
const multer = require('multer');
const app = express();

//CREATE EXPRESS APP
app.use(bodyParser.urlencoded({extended: true}))
 
//ROUTES WILL GO HERE
app.get('/', function(req, res) {
    res.json({ message: 'WELCOME' });   
});
 
app.listen(3000, () => console.log('Server started on port 3000'));

sau khi tạo file app.js, ta chạy command để start:

node app

Tạo form upload

Tạo file index.html, trong này ta sẽ khai báo form để tiến hành upload file

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>MY APP</title>
</head>
<body>
   
 
 <!--  SINGLE FILE -->
<form action="/uploadfile" enctype="multipart/form-data" method="POST"> 
   <input type="file" name="myFile" />
   <input type="submit" value="Upload a file"/>
</form>
 
 
<!-- MULTIPLE FILES -->
 
<form action="/uploadmultiple"  enctype="multipart/form-data" method="POST">
  Select images: <input type="file" name="myFiles" multiple>
  <input type="submit" value="Upload your files"/>
</form>
 
  <!--   PHOTO-->
 
<form action="/upload/photo" enctype="multipart/form-data" method="POST"> 
  <input type="file" name="myImage" accept="image/*" />
  <input type="submit" value="Upload Photo"/>
</form>
 
</body>
</html>

Cập nhật lại file app.js để hiển thị form

// ROUTES
app.get('/',function(req,res){
  res.sendFile(__dirname + '/index.html');
})

Xử lý file Uploads

Đầu tiên, ta cần xác định vị trí lưu trữ cho tệp.

Trong file app.js ta khai báo như sau:

// SET STORAGE
var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, 'uploads')
    },
    filename: function (req, file, cb) {
        console.log(file);
        cb(null, Date.now() + '-' + file.originalname)
    }
});
 
var upload = multer({ storage: storage })

Lưu ý:
Khi ta xử lý upload file sẽ dễ sinh ra lỗi vì folder uploads chưa tồn tại. Ta phải tạo thủ công, rất phức tạp nếu hệ thống chúng ta phải xử lý media phức tạp (nhiều folder theo id, …).

Ta thay đổi lại một xíu:
Ta cài package để hỗ trợ việc tạo folder:

npm i fs-extra

Cập nhật lại file app.js

const fsExtra = require('fs-extra');

// SET STORAGE
var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        let path = 'uploads';
        if (!fsExtra.existsSync(path)) {
            fsExtra.mkdirSync(path)
        }
        cb(null, path)
    },
    filename: function (req, file, cb) {
        console.log(file);
        cb(null, Date.now() + '-' + file.originalname)
    }
});

Xử lý Single File

Trong file index.html, ta đã khai báo form với action, bây giờ khai báo action để tiến hành upload file. Mở file app.js và cập nhật đoạn code vào:

app.post('/uploadfile', upload.single('myFile'), (req, res, next) => {
  const file = req.file
  if (!file) {
    const error = new Error('Please upload a file')
    error.httpStatusCode = 400
    return next(error)
  }
  res.send(file)
})

Lưu ý: tên của trường file phải giống với đối số ‘myFile’ được truyền vào hàm upload.single.

Xử lý Uploading Multiple Files

Tương tự như trên, ta chỉ thay đổi 1 xíu thôi:

//Uploading multiple files
app.post('/uploadmultiple', upload.array('myFiles', 12), (req, res, next) => {
  const files = req.files
  if (!files) {
    const error = new Error('Please choose files')
    error.httpStatusCode = 400
    return next(error)
  }
  res.send(files)
})

Số 12 truyền vào hàm upload.array là số lượng tối da cho phép upload. Nếu không giới hạn ta không cần truyền vào.

Cuối cùng phần upload hình ảnh tương tự như upload file phía trên

Truy cập file (hình ảnh)

Đến đây ta vẫn chưa thể truy xuất đến file (ở đây chủ yếu là hình ảnh) một cách trực tiếp trên url được. Các bạn có thể thử truy cập theo đường dẫn
http://localhost:3000/uploads/
Một file bất kì nào đó(hình ảnh càng tốt) sẽ báo Cannot Get …

Ta cần set static file cho folder chứa những file mà người dùng được phép truy cập đến.
Cập nhật một xíu file app.js

app.use('/uploads', express.static('uploads'));

Khi này ta reload sẽ trả về được file ta truy cập đến.

Nếu không truyền '/uploads' vào thì nó tính folder uploads là root và ta bỏ uploads trên url đi.

Thông thường các file css, js, image, … các file mà người dùng có quyền truy cập, ta tạo folder public và bỏ hết tất cả vào đó.

Kết luận

Mình vừa chia sẻ một số kiến thức về việc upload file. Việc sử lý đọc ghi file còn nhiều câu chuyện phía sau nữa. Dần dần ta sẽ đụng đến.

Nguồn tham khảo:

Rất mong được sự ủng hộ của mọi người để mình có động lực ra những bài viết tiếp theo.
{\__/}
( ~.~ )
/ > ♥️ I LOVE YOU 3000

JUST DO IT!


Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source Nguyễn Quang Đạt !
Comments
  TOC