Hướng dẫn upload file multipart/form-data nodejs - tải lên tệp multipart/form-data nodejs

Xin chào các bạn, chúng ta cùng bắt đầu bài số 13 trong loạt series Lập trình web NodeJS với ExpressJS các bạn nhé :))) bài số 13 trong loạt series Lập trình web NodeJS với ExpressJS các bạn nhé :)))

Bài hôm nay mình sẽ hướng dẫn các bạn làm việc với Multer để chúng ta có thể xử lý upload một hoặc nhiều files với Express và Node.js nhé.

Thực đơn bao gồm:


1. Multer là gì?

Khi client upload files lên server (thường được gửi qua một biểu mẫu), các tệp này sẽ được mã hóa dưới dạng dữ liệu multipart/form-data. Multer là một middleware giúp Express và Nodejs dễ dàng xử lý dữ liệu multipart/form-data này.upload files lên server (thường được gửi qua một biểu mẫu), các tệp này sẽ được mã hóa dưới dạng dữ liệu multipart/form-data. Multer là một middleware giúp Express và Nodejs dễ dàng xử lý dữ liệu multipart/form-data này.


2. Cài đặt, xử lý upload file với Multer

Trước tiên ta sẽ đi cài đặt express và multer trước đã:

npm install express

npm install multer

File index.js:index.js:

const express = require('express');
const multer = require('multer');
const port = 3000;
const app = express();

//cấu hình lưu trữ file khi upload xong
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
      //files khi upload xong sẽ nằm trong thư mục "uploads" này - các bạn có thể tự định nghĩa thư mục này
      cb(null, 'uploads') 
    },
    filename: function (req, file, cb) {
      // tạo tên file = thời gian hiện tại nối với số ngẫu nhiên => tên file chắc chắn không bị trùng
      const filename = Date.now() + '-' + Math.round(Math.random() * 1E9) 
      cb(null, filename + '-' + file.originalname )
    }
  })
//Khởi tạo middleware với cấu hình trên, lưu trên local của server khi dùng multer
const upload = multer({ storage: storage })

//route hiển thị form upload file
app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index.html');
})

//route xử lý upload single file
// "middleware multer "upload.single('formFile')" xử lý upload single file
// ví dụ sử dụng cho upload 1 ảnh như: avatar, cover,...
/* 
    Lưu ý: upload.single('formFile') - tên của thuộc tính name trong input 
    phải giống với 'formfile" trong hàm upload.single
*/
app.post('/uploadfile', upload.single('formFile'), (req, res, next) => {
    //nhận dữ liệu từ form
    const file = req.file;
    // Kiểm tra nếu không phải dạng file thì báo lỗi
    if (!file) {
        const error = new Error('Upload file again!')
        error.httpStatusCode = 400
        return next(error)
      }

    // file đã được lưu vào thư mục uploads
    // gọi tên file: req.file.filename và render ra màn hình
    res.sendFile(__dirname + `/uploads/${req.file.filename}`);
})

//route xử lý upload multiple file
// "middleware multer "upload.array('formFileMultiple', 3)" xử lý upload multiple file 
// ví dụ sử dụng cho chứa năng upload các hình ảnh của sản phẩm, gallery ảnh,...
/* 
    Lưu ý:  - upload.array('formFileMultiple') - tên của thuộc tính name trong input 
    phải giống với 'formFileMultiple" trong hàm upload.array
            - upload.array('fieldname, maxcount): maxcount: số lượng file tối đa upload trong 1 lần
            như code phía dưới là tối đa 3 file trong 1 lần upload
*/
app.post('/uploadmultiple', upload.array('formFileMultiple', 3), (req, res, next) => {
    //nhận dữ liệu từ form mảng thông số của các file upload
    const files = req.files;
    // Kiểm tra nếu không phải dạng file thì báo lỗi
    if (!files) {
        const error = new Error('Upload files again')
        error.httpStatusCode = 400
        return next(error)
      }
    
    // files đã được lưu vào thư mục uploads
    // hiển thị thông số các ảnh ra màn hình
    res.send(files);
})

app.listen(3000, () => {
    console.log(`Server started on port ${port}`)
})

File upload.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Upload Files</title>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
</head>
<body>

    <!-- UPLOAD SINGLE FILE -->
    <div class="mb-3">
        <form action="/uploadfile" enctype="multipart/form-data" method="POST"> 
            <label for="formFile" class="form-label">Default file input example</label>
            <input class="form-control" type="file" id="formFile" name="formFile">
            <input type="submit" value="Upload a file"/>
        </form>
    </div>

    <!-- UPLOAD MULTIPLE FILES -->
    <div class="mb-3">
        <form action="/uploadmultiple"  enctype="multipart/form-data" method="POST">
            <label for="formFileMultiple" class="form-label">Multiple files input example</label>
            <input class="form-control" type="file" id="formFileMultiple" name="formFileMultiple" multiple>
            <input type="submit" value="Upload multiple file"/>
        </form>
    </div>

 
</body>
</html>

Khởi động: node index, và kết quả khi upload single file:

Hướng dẫn upload file multipart/form-data nodejs - tải lên tệp multipart/form-data nodejs

Thử với multiple file:

Hướng dẫn upload file multipart/form-data nodejs - tải lên tệp multipart/form-data nodejs

Thư mục uploads:uploads:

Hướng dẫn upload file multipart/form-data nodejs - tải lên tệp multipart/form-data nodejs

Okay. Vậy là mình đã xong phần hướng dẫn upload file/ multiple files với multer rồi. Các bạn có thể xem một số chức năng nâng cao của multer tại: https://www.npmjs.com/package/multermulter rồi. Các bạn có thể xem một số chức năng nâng cao của multer tại: https://www.npmjs.com/package/multer

Full source code (github): https://github.com/chauitcode/express-upload: https://github.com/chauitcode/express-upload


Hy vọng qua bài này, các bạn đã nắm được kiến thức sử dụng multer để upload file cho ứng dụng của mình nhé.

Nếu có thắc mắc gì hay góp ý, mong các bạn để lại comment để mình phản hồi và cập nhật nhanh nhất có thể. Cảm ơn các bạn đã dành thời gian theo dõi

Hẹn mọi người vào bài tiếp theo!!! Xin cáo từ :xD