React使用Multer和Express.js单个文件上传

React使用Multer和Express.js单个文件上传

当我们想要添加上传或删除文件的功能时,文件存储变得至关重要,无论是用于网站还是个人用途。使用Express的文件存储项目旨在开发一个网络应用程序,为用户提供安全高效的在线文件存储和管理方式。通过Express,我们将能够创建一个用户友好的应用程序,轻松上传、删除和显示文件。让我们开始这个令人兴奋的项目吧!

最终输出的预览:

React使用Multer和Express.js单个文件上传

先决条件和技术:

  • Express:Express将被用于构建整个文件存储的后端。
  • Multer:Multer模块将被用于上传文件。
  • Ejs:EJS将被用于渲染HTML页面。
  • Bootstrap:Bootstrap将被用于优雅的页面设计和展示。

方法:

我们将利用Express来开发整个后端,Multer模块将被用于文件上传。应用程序将包括三个路由:上传、删除和查看。上传路由将用于文件上传,删除路由将用于删除特定文件,查看路由将用于显示所有文件。HTML页面将用于显示所有文件,以及上传和删除的选项。文件将存储在服务器的/file storage文件夹中,应用程序将支持所有类型的文件。

功能:

  • 文件上传: 此选项允许用户从计算机上传文件到服务器。
  • 文件删除: 此选项删除服务器上存储的选定文件,如果文件未找到,则会抛出错误。
  • 查看所有文件: 此选项在HTML页面上显示从服务器上传的所有文件。可以点击链接查看文件。

    创建项目的步骤:

步骤1: 首先,我们需要使用以下命令创建React应用程序

npx create-react-app <<Project_Name>>

步骤2: 导航到文件夹

cd <<Project_Name>>

步骤3 : 使用下面的命令安装以下软件包。

npm install express multer ejs

步骤4: 现在在项目文件夹中创建app.js文件。我们首先设置express应用程序创建express app实例。配置app使用EJS。对于EJS,在项目文件夹内创建/views文件夹。这个文件夹将包含我们的HTML代码。

项目结构:

React使用Multer和Express.js单个文件上传

package.json 中的 更新的依赖项 将会如下所示:

{  
  "name": "gfg-filestorage",  
  "version": "1.0.0",  
  "description": "",  
  "main": "app.js",  
  "scripts": {  
    "test": "echo \"Error: no test specified\" && exit 1",  
    "start": "node app.js"  
  },  
  "keywords": [],  
  "author": "",  
  "license": "ISC",  
  "dependencies": {  
    "ejs": "^3.1.9",  
    "express": "^4.18.2",  
    "multer": "^1.4.5-lts.1"  
  }  
}

示例:

  • App.js: 这是主服务器文件,我们将在此定义所有路由并启动服务器以监听端口3000。
  • index.ejs: 此文件将包含我们正在制作的项目的视图或模板设计,我们正在使用EJS作为视图引擎。
// app.js 
const express = require('express'); 
const multer = require('multer'); 
const path = require('path'); 
const fs = require('fs'); 
  
const app = express(); 
const port = 3000; 
  
app.set('view engine', 'ejs'); 
  
app.set('views', path.join(__dirname, 'views')); 
  
const storage = multer.diskStorage({ 
  destination: (req, file, cb) => { 
    cb(null, 'filestorage/'); 
  }, 
  filename: (req, file, cb) => { 
    const fileName = `{Date.now()}-{file.originalname}`; 
    cb(null, fileName); 
  }, 
}); 
  
const upload = multer({ storage }); 
  
app.use('/uploads', express.static(path.join(__dirname, 'filestorage'))); 
  
app.get('/', (req, res) => { 
  res.render('index') 
}); 
  
app.post('/upload', upload.single('file'), (req, res) => { 
    res.redirect('/') 
}); 
  
app.delete('/delete/:fileName', (req, res) => { 
  const fileName = req.params.fileName; 
  const filePath = path.join(__dirname, 'filestorage', fileName); 
  
  if (fs.existsSync(filePath)) { 
    fs.unlinkSync(filePath); 
    res.send(`File "{fileName}" has been deleted.`); 
  } else { 
    res.status(404).send(`File "{fileName}" not found.`); 
  } 
}); 
  
app.get('/view', (req, res) => { 
  const uploadDirectory = path.join(__dirname, 'filestorage'); 
  fs.readdir(uploadDirectory, (err, files) => { 
    if (err) { 
      console.error(err); 
      res.status(500).send('Error reading the upload directory.'); 
    } else { 
      res.json({ files }); 
    } 
  }); 
}); 
  
app.listen(port, () => { 
  console.log(`Server is running on port ${port}`); 
}); 

Javascript代码

// index.ejs 
<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="UTF-8"> 
    <meta name="viewport" 
          content="width=device-width, initial-scale=1.0"> 
    <title>File Storage App</title> 
    <script src= 
"https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.9.4/umd/popper.min.js"> 
    </script> 
    <script src= 
"https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.min.js"> 
    </script> 
    <link href= 
"https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css" 
          rel="stylesheet"> 
  
    <link href= 
"https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.3.0/css/all.min.css" 
          rel="stylesheet"> 
</head> 
<body> 
    <div class="container"> 
        <h1 class="mt-5 text-success">GeeksForGeeks File Storage</h1> 
  
        <h2 class="mt-4">Upload File</h2> 
        <form action="/upload" method="POST" 
              enctype="multipart/form-data"> 
            <div class="mb-3"> 
                <input type="file" name="file" 
                       class="form-control" required> 
            </div> 
            <button type="submit" class="btn btn-primary">Upload</button> 
        </form> 
  
        <h2 class="mt-4">Delete File</h2> 
        <form id="deleteForm"> 
            <div class="mb-3"> 
                <select id="fileSelect" name="fileName"
                        class="form-select"> 
                </select> 
            </div> 
            <button type="button" class="btn btn-danger" 
                    onclick="deleteFile()">Delete</button> 
        </form> 
  
        <h2 class="mt-4">Uploaded Files</h2> 
        <ul id="fileList" class="list-group"> 
        </ul> 
    </div> 
  
  
  
    <script> 
        function populateFileListWithIcons() { 
            fetch('/view') 
                .then(response => response.json()) 
                .then(data => { 
                    const fileList = document.getElementById('fileList'); 
                    fileList.innerHTML = ''; 
  
                    data.files.forEach(fileName => { 
                        const listItem = document.createElement('li'); 
      listItem.className = 'list-group-item d-flex justify-content-between align-items-center'; 
  
                        const fileExtension = fileName.split('.').pop(); 
  
                        const iconSpan = document.createElement('span'); 
                        iconSpan.className = 'me-3'; 
                        iconSpan.innerHTML = getFileIconHTML(fileExtension); 
  
                        const fileLink = document.createElement('a'); 
                        fileLink.href = `/uploads/{fileName}`; 
                        fileLink.textContent = fileName; 
  
                        listItem.appendChild(iconSpan); 
                        listItem.appendChild(fileLink); 
  
                        fileList.appendChild(listItem); 
                    }); 
                }) 
                .catch(error => console.error(error)); 
        } 
  
        function getFileIconHTML(fileExtension) { 
            const iconClasses = { 
                pdf: 'far fa-file-pdf', 
                doc: 'far fa-file-word', 
                docx: 'far fa-file-word', 
                xls: 'far fa-file-excel', 
                xlsx: 'far fa-file-excel', 
                ppt: 'far fa-file-powerpoint', 
                pptx: 'far fa-file-powerpoint', 
                txt: 'far fa-file-alt', 
                jpg: 'far fa-file-image', 
                jpeg: 'far fa-file-image', 
                png: 'far fa-file-image', 
                gif: 'far fa-file-image', 
                default: 'far fa-file'
            }; 
  
          return `<i class="{iconClasses[fileExtension.toLowerCase()] || iconClasses['default']}"> 
      </i>`; 
        } 
  
        function deleteFile() { 
            const deleteForm = document.getElementById('deleteForm'); 
            const formData = new FormData(deleteForm); 
  
            fetch(`/delete/${formData.get('fileName')}`, { 
                method: 'DELETE', 
            }) 
                .then(response => response.text()) 
                .then(message => { 
                    alert(message); 
                    populateFileListWithIcons(); 
                    populateDeleteOptions(); 
                }) 
                .catch(error => console.error(error)); 
        } 
  
        function populateDeleteOptions() { 
            fetch('/view') 
                .then(response => response.json()) 
                .then(data => { 
                    const fileSelect = document.getElementById('fileSelect'); 
                    fileSelect.innerHTML = ''; 
                    data.files.forEach(fileName => { 
                        const option = document.createElement('option'); 
                        option.value = fileName; 
                        option.textContent = fileName; 
                        fileSelect.appendChild(option); 
                    }); 
                }) 
                .catch(error => console.error(error)); 
        } 
  
        populateFileListWithIcons(); 
        populateDeleteOptions(); 
    </script> 
</body> 
</html> 

运行应用程序的步骤:

第 1 步 在终端中输入以下命令。

npm start

第 2 步 打开网页浏览器并输入以下URL

http://localhost:3000/

输出:

React使用Multer和Express.js单个文件上传
是一个用于创建和维护Web页面的标记语言。它由一系列的元素(标签)组成,这些标签有不同的功能和用途,例如标记文本、插入图像、添加链接等。HTML使用尖括号(<>)将标签括起来,并使用属性为标签提供更多的信息。在浏览器中,HTML会被解析并显示为可视化的Web页面。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程