JavaScript >> Javascript 文檔 >  >> Node.js

使用 Express 和 Multer 在 Node.js 中處理文件上傳

簡介

用戶不僅消費數據,他們還生產數據並上傳數據。他們可以通過信使或電子郵件等應用程序向特定收件人發送數據,或將文件上傳到社交網絡和數據流媒體平台,如 Facebook 或 YouTube。

話雖如此,如今幾乎每個交互式網站都支持文件上傳。

文件上傳庫

NPM 上有幾個可用的 Node 庫,可以簡化驗證和上傳文件到服務器的過程。其中,如今最受歡迎的選擇是 Multer、Formidable 和 Multiparty。

它們都有穩定的版本,並得到了開源開發者在線社區的支持。

什麼是 Multer?

穆特 是一個流行的 Node.js 中間件,用於處理 multipart/form-data 要求。它利用 busboy 解析通過 HTML 表單接收到的任何數據。這大大提高了它的性能,因為 busboy 模塊在分析表單數據方面是無與倫比的。

Multer 在處理 multipart/form-data 時為我們提供了控制和靈活性 requests - 我們獲取有關每個上傳文件的詳細信息、添加自定義存儲引擎的能力、根據我們的需要驗證文件、設置上傳文件限制的能力等。

項目設置

由於我們不會將圖像存儲在數據庫中,而是將圖像存儲在一個簡單的文件夾中,為了簡潔起見,讓我們在項目文件夾中創建另一個文件夾並將其命名為 uploads .

現在,讓我們安裝 Express:

$ npm i express

最後,讓我們安裝 Multer:

$ npm i multer

項目實施

此時,我們已經準備好編寫一些代碼,從我們將用來收集信息的 HTML 表單開始。

讓我們從上傳單個文件的表單開始:

<form method="POST" action="/upload-profile-pic" enctype="multipart/form-data">
    <div>
        <label>Select your profile picture:</label>
        <input type="file" name="profile_pic" />
    </div>
    <div>
        <input type="submit" name="btn_upload_profile_pic" value="Upload" />
    </div>
</form>

然後用一個允許我們上傳多個文件的表單:

<form method="POST" action="/upload-multiple-images" enctype="multipart/form-data">
    <div>
        <label>Select multiple images:</label>
        <input type="file" name="multiple_images" multiple />
    </div>
    <div>
        <input type="submit" name="btn_upload_multiple_images" value="Upload" />
    </div>
</form>

您可以將這些表格放在不同的頁面上,也可以放在同一個頁面上。就本教程而言,它們是一個接一個:

HTML 表單非常簡單,接受 multipart/form-data 並路由到處理其請求的適當函數。

快遞申請

準備好表單後,我們可以處理通過 Express 上傳和驗證文件的實際邏輯。

讓我們創建一個名為 app.js 的文件 在項目根目錄中,首先導入所需的模塊:

const express = require('express');
const multer = require('multer');
const path = require('path');

現在,讓我們創建我們的 Express 應用:

const app = express();

最後,讓我們設置它運行的端口:

免費電子書:Git Essentials

查看我們的 Git 學習實踐指南,其中包含最佳實踐、行業認可的標準以及隨附的備忘單。停止谷歌搜索 Git 命令並真正學習 它!

const port = process.env.PORT || 3000;

public 我們根文件夾的目錄包含我們要提供的靜態文件,所以讓我們使用 express.static 將其設置為靜態目錄 :

app.use(express.static(__dirname + '/public'));

至此,我們來定義圖片的存儲位置:

const storage = multer.diskStorage({
    destination: function(req, file, cb) {
        cb(null, 'uploads/');
    },

    // By default, multer removes file extensions so let's add them back
    filename: function(req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
    }
});

最後,讓我們使用我們之前設置的端口運行應用程序:

app.listen(port, () => console.log(`Listening on port ${port}...`));

文件驗證和上傳

出於基本的安全原因,我們希望在將文件上傳到我們的服務器之前對其進行驗證。讓我們編輯 app.js 文件並添加這兩個功能:

app.post('/upload-profile-pic', (req, res) => {
    // 'profile_pic' is the name of our file input field in the HTML form
    let upload = multer({ storage: storage, fileFilter: helpers.imageFilter }).single('profile_pic');

    upload(req, res, function(err) {
        // req.file contains information of uploaded file
        // req.body contains information of text fields, if there were any

        if (req.fileValidationError) {
            return res.send(req.fileValidationError);
        }
        else if (!req.file) {
            return res.send('Please select an image to upload');
        }
        else if (err instanceof multer.MulterError) {
            return res.send(err);
        }
        else if (err) {
            return res.send(err);
        }

        // Display uploaded image for user validation
        res.send(`You have uploaded this image: <hr/><img src="${req.file.path}" width="500"><hr /><a href="./">Upload another image</a>`);
    });
});

在這裡,我們接受了 HTTP POST 請求,其中包含圖像信息。真正負責上傳功能的函數是 multer().single() 方法。

您可能已經註意到 fileFilter: helpers.imageFilter 但我們還沒有創建/導入 helpers 文件。因此,讓我們在項目目錄中創建一個新文件並將其命名為 helpers.js .這裡我們將編寫一些代碼,用於檢查提交的文件是否為圖片。

const imageFilter = function(req, file, cb) {
    // Accept images only
    if (!file.originalname.match(/\.(jpg|JPG|jpeg|JPEG|png|PNG|gif|GIF)$/)) {
        req.fileValidationError = 'Only image files are allowed!';
        return cb(new Error('Only image files are allowed!'), false);
    }
    cb(null, true);
};
exports.imageFilter = imageFilter;

當然,要使用這個模塊,我們必須在 app.js 的頂部導入它 文件:

const helpers = require('./helpers');

現在,我們可以運行我們的應用程序並驗證它是否正常工作:

上傳多個文件

上傳多個文件本質上與上傳單個文件相同。雖然,而不是 multer().single() 函數,我們使用 multer().array() 功能:

app.post('/upload-multiple-images', (req, res) => {
    // 10 is the limit I've defined for number of uploaded files at once
    // 'multiple_images' is the name of our file input field
    let upload = multer({ storage: storage, fileFilter: helpers.imageFilter }).array('multiple_images', 10);

    upload(req, res, function(err) {
        if (req.fileValidationError) {
            return res.send(req.fileValidationError);
        }
        else if (...) // The same as when uploading single images

        let result = "You have uploaded these images: <hr />";
        const files = req.files;
        let index, len;

        // Loop through all the uploaded images and display them on frontend
        for (index = 0, len = files.length; index < len; ++index) {
            result += `<img src="${files[index].path}" width="300" style="margin-right: 20px;">`;
        }
        result += '<hr/><a href="./">Upload more images</a>';
        res.send(result);
    });
});

現在,驗證一切是否正常:

結論

用戶不僅消費數據,他們還生產數據,並且在許多情況下,需要將其上傳到 Web 服務器。他們可以通過信使或電子郵件等應用程序將數據發送給特定的收件人,或者他們可以將文件上傳到社交網絡和數據流媒體平台,如 Facebook 或 YouTube。

在本文中,我們使用 Express.js 和 Multer 庫在一個簡單的 Web 應用程序中處理基本的文件上傳功能。


Tutorial JavaScript 教程
  1. Roda,路由樹 Web 工具包:教程

  2. 使用 JavaScript 格式化日期

  3. 關於 React 渲染道具與 HOC

  4. 2021 年成為開發者指南

  5. 2022年沒有什麼新鮮事了?

  6. 使用 Phoenix LiveView 將文件上傳到 Google Drive

  7. Git 工作流策略:單個存儲庫中的多個團隊

  1. 快速簡單的 JS 視差效果

  2. TravelZoom- Mule 與日常 API 的集成

  3. 適合初級開發者的三個有用規則

  4. 所有程序員都應該知道的數字 - 系統設計基礎

  5. JavaScript 的 AJAX 固定裝置

  6. 創建一個基本的 JavaScript 對象

  7. 將 React 應用程序連接到 firebase

  1. 使用 useImperativeHandle 和 jspdf 在 React 中創建 Pdf Saver 和 Print Previewer

  2. 如何調試 JavaScript 代碼

  3. 從零開始的 JavaScript 應用程序

  4. 未來的 Javascript:時間