首页>>前端>>Node->Reactjs + Nodejs + Express + Mongodb搭建[图片上传/预览]项目(下)

Reactjs + Nodejs + Express + Mongodb搭建[图片上传/预览]项目(下)

时间:2023-11-29 本站 点击:0

Reactjs + Nodejs + Express + Mongodb 搭建[图片上传/预览]前后端项目

概述

图片上传功能,在日常的项目开发中是很常见的功能,今天我们就来说说使用 Reactjs + Nodejs + Express + Mongodb 搭建前后端图片上传的例子

我们先看看完成后的效果

跟随本示例学习,你也可以搭建出来。

后端部分

实现的功能:

图片上传功能

图片上传显示进度条功能

图片预览功能

图片列表功能

图片下载功能

后端使用的技术/数据库:

Nodejs

Express

Multer

Mongodb

Multer-gridfs-storage

Cors

后端部分我们使用 Nodejs + Express + Multer + Mongodb 来搭建图片上传的项目,配合前端 Reactjs + Axios 来共同实现图片上传的前后端项目。

后端项目目录结构

├── README.md├── node_modules├── package-lock.json├── package.json└── src    ├── config    │   └── db.js    ├── controllers    │   ├── home.js    │   └── upload.js    ├── middleware    │   └── upload.js    ├── routes    │   └── index.js    ├── server.js    └── views        └── index.html

config/db.js:包括 MongoDBMulter 的配置(url、数据库、图像存储桶)。

routes/index.js:定义从视图调用的端点的路由,使用控制器来处理请求。

controllers: home.js返回 views/index.html upload.js处理上传、存储、显示和下载图像

middleware/upload.js:初始化 Multer GridFs 存储引擎(包括 MongoDB)并定义中间件函数。

server.js:初始化路由,配置 CORS,入口文件

后端项目我们提供以下几个API

文件上传接口

文件列表获取接口

使用 url 下载文件接口

我们可以使用 postman 工具先看下接口的情况,如下图

文件上传接口

获取文件列表接口

打开数据库连接工具,可以看到,数据库里,已经有上传的文件了

创建项目 配置模块

我们先使用命令 mkdir 创建一个空文件夹,然后 cd 到文件夹里面

这个文件夹就是我们的项目文件夹

mkdir nodejs-express-upload-filescd nodejs-express-upload-files

接着使用命令

npm init

初始化项目,接着安装项目需要的依赖包, 输入如下命令

npm install express cors multer multer-gridfs-storage mongodb

package.js 文件

{  "name": "nodejs-express-upload-files",  "version": "1.0.0",  "description": "Node.js upload multiple files/images to MongoDB",  "main": "src/server.js",  "scripts": {    "test": "echo \"Error: no test specified\" && exit 1"  },  "keywords": [    "node",    "upload",    "multiple",    "files",    "images",    "mongodb"  ],  "license": "ISC",  "dependencies": {    "cors": "^2.8.5",    "express": "^4.17.1",    "mongodb": "^4.1.3",    "multer": "^1.4.3",    "multer-gridfs-storage": "^5.0.2"  }}

配置 MongoDB 数据库

config/db.js

module.exports = {  url: "mongodb://localhost:27017/",  database: "files_db",  imgBucket: "photos",};

配置图片上传存储的中间件

middleware/upload.js

const util = require("util");const multer = require("multer");const { GridFsStorage } = require("multer-gridfs-storage");const dbConfig = require("../config/db");var storage = new GridFsStorage({  url: dbConfig.url + dbConfig.database,  options: { useNewUrlParser: true, useUnifiedTopology: true },  file: (req, file) => {    const match = ["image/png", "image/jpeg"];    if (match.indexOf(file.mimetype) === -1) {      const filename = file.originalname;      return filename;    }    return {      bucketName: dbConfig.imgBucket,      filename: file.originalname    };  }});var uploadFiles = multer({ storage: storage }).array("file", 10);var uploadFilesMiddleware = util.promisify(uploadFiles);module.exports = uploadFilesMiddleware;

这里我们定义一个 storage 的配置对象 GridFsStorage

url: 必须是指向 MongoDB 数据库的标准 MongoDB 连接字符串。multer-gridfs-storage 模块将自动为您创建一个 mongodb 连接。

options: 自定义如何建立连接

file: 这是控制数据库中文件存储的功能。该函数的返回值是一个具有以下属性的对象:filename, metadata, chunkSize, bucketName, contentType... 我们还检查文件是否为图像file.mimetype。bucketName表示文件将存储在photos.chunks和photos.files集合中。

接下来我们使用multer模块来初始化中间件util.promisify()并使导出的中间件对象可以与async-await.

single()带参数的函数是input标签的名称

创建文件上传的控制器

controllers/upload.js

这个文件主要用于图片上传,我们创建一个名 upload 函数,并将这个函数导出去

我们使用 文件上传中间件函数处理上传的文件

使用 Multer 捕获相关错误

返回响应

文件列表数据获取和下载

getListFiles 函数主要是获取 photos.files,返回 url, name, id

download(): 接收文件 id 作为输入参数,从 mongodb 内置打开下载流GridFSBucket,然后 response.write(chunk) API 将文件传输到客户端。

const upload = require("../middleware/upload");const dbConfig = require("../config/db");const MongoClient = require("mongodb").MongoClient;const GridFSBucket = require("mongodb").GridFSBucket;const url = dbConfig.url;const baseUrl = "http://localhost:8080/files/";const mongoClient = new MongoClient(url);const uploadFiles = async (req, res) => {  try {    await upload(req, res);    console.log(req.files);    if (req.files.length <= 0) {      return res        .status(400)        .send({ message: "You must select at least 1 file." });    }    return res.status(200).send({      message: "文件上传成功",    });    // console.log(req.file);    // if (req.file == undefined) {    //   return res.send({    //     message: "You must select a file.",    //   });    // }    // return res.send({    //   message: "File has been uploaded.",    // });  } catch (error) {    console.log(error);    if (error.code === "LIMIT_UNEXPECTED_FILE") {      return res.status(400).send({        message: "Too many files to upload.",      });    }    return res.status(500).send({      message: `Error when trying upload many files: ${error}`,    });    // return res.send({    //   message: "Error when trying upload image: ${error}",    // });  }};const getListFiles = async (req, res) => {  try {    await mongoClient.connect();    const database = mongoClient.db(dbConfig.database);    const images = database.collection(dbConfig.imgBucket + ".files");    let fileInfos = [];    if ((await images.estimatedDocumentCount()) === 0) {        fileInfos = []    }    let cursor = images.find({})    await cursor.forEach((doc) => {      fileInfos.push({        id: doc._id,        name: doc.filename,        url: baseUrl + doc.filename,      });    });    return res.status(200).send(fileInfos);  } catch (error) {    return res.status(500).send({      message: error.message,    });  }};const download = async (req, res) => {  try {    await mongoClient.connect();    const database = mongoClient.db(dbConfig.database);    const bucket = new GridFSBucket(database, {      bucketName: dbConfig.imgBucket,    });    let downloadStream = bucket.openDownloadStreamByName(req.params.name);    downloadStream.on("data", function (data) {      return res.status(200).write(data);    });    downloadStream.on("error", function (err) {      return res.status(404).send({ message: "Cannot download the Image!" });    });    downloadStream.on("end", () => {      return res.end();    });  } catch (error) {    return res.status(500).send({      message: error.message,    });  }};module.exports = {  uploadFiles,  getListFiles,  download,};

定义路由

routes 文件夹中,使用 Express Routerindex.js 中定义路由

const express = require("express");const router = express.Router();const homeController = require("../controllers/home");const uploadController = require("../controllers/upload");let routes = app => {  router.post("/upload", uploadController.uploadFiles);  router.get("/files", uploadController.getListFiles);  router.get("/files/:name", uploadController.download);  return app.use("/", router);};module.exports = routes;

POST"/upload"调用 uploadFiles 控制器的功能。

获取/files图像列表。

GET/files/:name下载带有文件名的图像。

创建 Express 服务器

server.js

const cors = require("cors");const express = require("express");const app = express();const initRoutes = require("./routes");var corsOptions = {  origin: "http://localhost:8081"};app.use(cors(corsOptions));app.use(express.urlencoded({ extended: true }));initRoutes(app);let port = 8080;app.listen(port, () => {  console.log(`Running at localhost:${port}`);});

这里我们导入了 expresscors,

Express 用于构建 Rest api

Cors 提供 Express 中间件以启用具有各种选项的 CORS

创建一个 Express 应用程序,然后使用方法添加 Cors 中间件 在端口 8080 上侦听传入请求。

运行项目并测试

在项目根目录下在终端中输入命令 node src/server.js,  控制台显示

Running at localhost:8080

使用 postman 工具测试,ok 项目正常运行

文件上传接口

获取文件列表接口

打开数据库连接工具,可以看到,数据库里,已经有上传的文件了

联调

我们先启动后端项目  node src/server.js, 接着再启动前端项目  npm start,

测试上传,获取等接口,一切正常。

到这里整个前后端「上传图片」功能示例就算完成了。

原文:https://juejin.cn/post/7103518888100364302


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Node/931.html