使用 multer 上传文件并传输到 Nodejs Express 应用程序上的专用文件夹

问题描述 投票:0回答:1
  1. 配置乘法器
  2. multer 配置为全局中间件
  3. 用于重新使用获取上传图像或图像路径的帮助器
  4. 将上传文件转移到专用文件夹
  5. 上传单个文件并传输到专用文件夹
  6. 上传多个文件并传输到专用文件夹
  7. 删除文件可重用助手
  8. 删除单个文件
  9. 删除多个文件
import multer from 'multer'
import path from 'path'
import fs from 'fs'

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        const uploadDir = path.join(__dirname, "../../public/files/");
        if (!fs.existsSync(uploadDir)) {
            fs.mkdirSync(uploadDir, { recursive: true });
        }
        cb(null, "public/files");
    },
    filename: (req, file, cb) => {
        const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
        cb(null, uniqueSuffix + '-' + file.originalname);
    },
});

const upload = multer({
    storage: storage,
    fileFilter: (req, file, cb) => {
        const supportedFile = /jpg|jpeg|png|webp|svg|pdf/;
        const extension = path.extname(file.originalname);

        if (supportedFile.test(extension)) {
            cb(null, true);
        } else {
            cb(new Error('Must be a jpg/png/jpeg/webp/svg file'), false);
        }
    },
});


export default upload;
node.js express multer
1个回答
0
投票
  1. 配置多路复用器
import multer from 'multer';
import path from 'path';
import fs from 'fs';
import { fileURLToPath } from 'url';
import { dirname } from 'path';

// Get __dirname equivalent in ES Modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        const uploadDir = path.join(__dirname, "../../public/files/");
        if (!fs.existsSync(uploadDir)) {
            fs.mkdirSync(uploadDir, { recursive: true });
        }
        cb(null, "public/files");
    },
    filename: (req, file, cb) => {
        const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
        cb(null, uniqueSuffix + '-' + file.originalname);
    },
});

const upload = multer({
    storage: storage,
    fileFilter: (req, file, cb) => {
        const supportedFile = /jpg|jpeg|png|webp|svg|pdf/;
        const extension = path.extname(file.originalname).toLowerCase();

        if (supportedFile.test(extension)) {
            cb(null, true);
        } else {
            cb(new Error('Must be a jpg/png/jpeg/webp/svg/pdf file'), false);
        }
    },
});

export default upload;
  1. 在主文件中使用multer配置为全局中间件例如:index.js / server.js),因此每个请求数据都必须使用form-data发送。
  // multer configure
    app.use(
        upload.fields([
            { name: "single", maxCount: 1 },
            { name: "multiple", maxCount: 10 },
        ])
    );
  1. 我正在使用助手来重新使用来上传图像图像路径
// single image file upload -> image path
const returnSingleFilePath = async (files, field = 'single') => {

    let filePath;

    if (files && Object.keys(files).length > 0) {
        if (Array.isArray(files)) {
            filePath = files[0].path;
        } else {
            filePath = files[field]?.[0]?.path;
        }
    }

    return filePath;
}

// mutiple image file upload -> image paths
const returnMultipleFilePath = async (files, field = 'multiple') => {

    let imagesPaths = [];

    if (files && Object.keys(files).length > 0) {
        files[field].map((item) => {
            imagesPaths.push(item.path);
        })
    }

    return imagesPaths;
}

export default {
    returnSingleFilePath,
    returnMultipleFilePath,
}
  1. 此外,我正在使用另一个助手在上传后将上传文件传输到专用文件夹。在此帮助中,再次为了重用,我使用两个函数来传输单个或多个图像。在这里,在根目录中将存在或创建 public 文件夹,然后在该文件夹内传输文件文件夹将自动创建并传输文件。
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { dirname } from 'path';

// Get __dirname equivalent in ES Modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

// Function to move file to specific folder
const singleFileTransfer = (filePath, destinationFolder) => {
    const fileName = path.basename(filePath);
    const newFilePath = path.join(__dirname, '../../public', destinationFolder, fileName);
    const fileUrl = `public/${destinationFolder}/${fileName}`; // the new URL of the file

    // Check if the destination folder exists, if not, create it
    if (!fs.existsSync(path.dirname(newFilePath))) {
        fs.mkdirSync(path.dirname(newFilePath), { recursive: true });
    }

    // Move the file to the destination folder
    fs.rename(filePath, newFilePath, (err) => {
        if (err) {
            console.log(`Error moving file: ${err}`);
        } else {
            console.log(`File moved successfully to ${newFilePath}`);
        }
    });

    return fileUrl;
}

// Function to move files to specific folder
const multipleFilesTransfer = async (imagePaths, destinationFolder) => {
    const paths = [];

    imagePaths.map((item) => {
        const newPath = singleFileTransfer(item, destinationFolder);
        paths.push(newPath);
    });

    return paths;
}

export {
    singleFileTransfer,
    multipleFilesTransfer
};
  1. 加载单个文件传输到专用文件夹
const Controller = async (req, res) => {

    const body = req.body && req.body.data ? JSON.parse(req.body.data) : {};

    // getting the images path
    if (req.files && Object.keys(req.files).length > 0) {
        if (req.files.single) {
            const imagePath = await returnFilePath.returnSingleFilePath(req.files, 'single');

            // transfer images to new folder and assign new paths
            if (imagePath) {
                const newImagePath = await singleFileTransfer(imagePath, "folderName")
                body.logo = newImagePath;
            }
        }
    }

    sendResponse(res, {
        statusCode: 200,
        success: true,
        message: 'Api called successfully!',
        data: body,
    });
}
  1. 上传多个文件传输到专用文件夹
const Controller = async (req, res) => {

    const body = req.body && req.body.data ? JSON.parse(req.body.data) : {};

    // getting the images path
    if (req.files && Object.keys(req.files).length > 0) {
        // upload images
        const imagePaths = await returnFilePath.returnMultipleFilePath(req.files);

        // transfer images to new folder and assign new paths
        let newImagePaths = [];
        if (imagePaths.length) {
            newImagePaths = await multipleFilesTransfer(imagePaths, "folderName")
            body.photos = newImagePaths;
        }
    }

    sendResponse(res, {
        statusCode: 200,
        success: true,
        message: 'Api called successfully!',
        data,
    });
}
  1. 删除文件我正在使用新的助手
import fs from 'fs';

const removeFile = async (imgPath) => {
    if (fs.existsSync(imgPath)) {
        fs.unlinkSync(imgPath);
        console.log(`File ${imgPath} deleted successfully`);
    } else {
        console.log(`File ${imgPath} does not exist`);
    }
}

export default removeFile;
  1. 删除单个文件,请在控制器中使用async
 await removeFile(item);
  1. 删除多个文件,请在控制器中使用async
 imagePaths.map(async (item) => {
     await removeFile(item);
 })
© www.soinside.com 2019 - 2024. All rights reserved.