我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何使用Node和MongoDB搭建一个图床或网盘

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何使用Node和MongoDB搭建一个图床或网盘

这篇“如何使用Node和MongoDB搭建一个图床或网盘”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“如何使用Node和MongoDB搭建一个图床或网盘”文章吧。

1 文章起源

这个项目比较简单,看完的同学就可以很快的搭建一个小网盘或者图床了。

2 起手式

2.1 概念

首先我们得先去了解一下Mongodb的文件储存(GridFS)是啥,因为我们都是基于 GridFS 来进行文件储存

2.2 我们需要什么

了解了大概概念后就可以着手安装我们必须的插件了

  • express (这是啥不用我多说)

  • body-parser (Node解析body的中间件)

  • ejs (模板引擎,快速开发就不搞前后端分离了,有兴趣的小伙伴可以用Vue/React来搭建小网盘)

  • gridfs-stream (轻松地与MongoDB GridFS之间传输文件。)

  • method-override (我们用form表单简单上传,因为form表单不支持put/delete请求方式,所以把它安排上了,小伙伴可自行使用Ajax,就不需要这么麻烦了)

  • mongoose (用于连接mongodb必不可少的插件)

  • multer (Multer是用于处理多部分/表单数据的node.js中间件,主要用于上传文件。它被编写在busboy之上,以实现最大效率。)

  • multer-gridfs-storage (Multer的GridFS存储引擎可将上传的文件直接存储到MongoDb。)

  • nodemon (热更新)

(推荐教程:Node入门)

以上就是我们需要准备的东西了

npm install express body-parser ejs gridfs-stream method-override mongoose multer multer-gridfs-storage// oryarn add express body-parser ejs gridfs-stream method-override mongoose multer multer-gridfs-storage

2.3 初始化一个项目

// 可自行补充信息// npm init

然后在根目录新建一个入口文件app.js,和页面 views/index.ejs

3 现在项目开始了

3.1 先将基础部分完事

将我们安装的包引入,再跑跑看看

const express = require('express')const path = require('path')const crypto = require('crypto')const mongoose = require('mongoose')const multer = require('multer')const GridFsStorage = require('multer-gridfs-storage')const GridFsStream = require('gridfs-stream')const methodOverride = require('method-override')const bodyParser = require('body-parser')

const app = express()app.set('view engine', 'ejs') // 设置模板引擎app.use(bodyParser.json()) app.use(methodOverride('_method'))app.get('/', (req, res) => {        res.render('index')    })})const port = 5000app.listen(port, () => {    console.log(`App listering on port ${port}`)})

一般来说启动了app.js的话我们在浏览器访问 http://localhost:5000 就能看到 views/index.ejs 中的界面了,如果没有,自行查看控制台是否报错

3.2 连接我们的Mongodb数据库

我这边用的本地mongodb数据库,线上也是一样的,我们可以用NoSQL manager for mongdb来查看我们数据库里面的数据,我们新建一个新的集合,我这边叫 grid_uploads。所以连接的话也是连接这个集合

// 数据库的链接const mongoURL = 'mongodb://localhost:27017/grid_uploads'

const connect = mongoose.createConnection(mongoURL, {    useNewUrlParser: true,    useUnifiedTopology: true})

3.3 美化一下界面(views/index.ejs)

作为一个小两年的前端工程师,已经练就了像素眼了,我们肯定不能把界面做的辣么丑对吧,眼睛过不去啊,所以我们简单的用bootstrap4来做个界面好了

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>文件上传</title>    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.0/dist/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">    <style>        img {            width: 100%;        }    </style></head><body>    <div class="container">        <div class="row">            <div class="col-md-6 m-auto">                <h3 class="text-center display-4 my-4">Mongo文件上传</h3>                <form action="/upload" method="POST" enctype="multipart/form-data">                    <div class="custom-file mb-3">                        <input type="file" name="file" id="file" class="custom-file-input">                        <label for="file" class="custom-file-label">选择文件</label>                    </div>                    <input class="btn btn-primary btn-block" type="submit" value="提交">                </form>                <hr>            </div>        </div>    </div></body><script class="lazy" data-src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script><script class="lazy" data-src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script><script class="lazy" data-src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.0/dist/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script></html>

3.4 做一些必须的处理

// 定义gfs变量,后续我们进行数据库文件操作的时候可不能少let gfs;connect.once('open', () => {// 监听数据库开启,通过 gridfs-stream 中间件和数据库进行文件的出入控制gfs = GridFsStream(connect.db, mongoose.mongo)gfs.collection('upload')// 它会在我们数据库中建立 upload.files(记录文件信息)  upload.chunks(存储文件块)})

// 使用 multer-gridfs-storage Multer 中间件来讲我们上传的附件直接存储到MongoDbconst storage = new GridFsStorage({    url: mongoURL,    file: (req, file) => {        return new Promise((resolve, reject) => {            // 下面注释部分是给文件进行重命名的,如果想要原文件名称可以自行使用 file.originalname 返回,            // 建议有时间的小伙伴存储两个文档,一个记录原文件名,一个记录加密文件名,然后返回到页面的时候可以将中文名返回去                        // crypto.randomBytes(16, (err, buf) => {            //     if (err) {            //         return reject(err)            //     }            //     const filename = buf.toString('hex') + path.extname(file.originalname)            //     const fileinfo = {            //         filename,            //         bucketName: 'upload'            //     }            //     resolve(fileinfo)            // })            const fileinfo = {                filename: new Date() + '-' + file.originalname,                bucketName: 'upload'            }            resolve(fileinfo)        })    }})const upload = multer({ storage })

3.5 写我们上传第一个文件的接口

app.post('/upload', upload.single('file'), (req, res) => {res.redirect('/')})

看起来简简单单,请记着这么几件事

  • views/index.ejs中 (input type=file 指定的name得和接口的upload.single('file') 一样

  • 上传完文件我们重定向回我们的首页 此时我们就可以在NoSql看到我们的两个文档有数据了

3.6 获取我们所有的文件信息

获取我们所有的文件

app.get('/files', (req, res) => {// 通过查找返回一个数组对象回去gfs.files.find().toArray((err, files) => {if (!files || files.length === 0) {return res.status(404).json({err: '文件不存在!'})}return res.json(files)})})

我们可以进行一些美化操作,比如我们可以将上传是图片的,返回到界面的话以图片显示,其他则以 a 标签的格式显示(可点击下载),所以我们可以将 views/index.ejs的界面进行美化改造(ejs语法用起来确实蛮麻烦的),进行重新排版以及添加删除按钮

<!DOCTYPE html><html lang="en">

<head>    <meta charset="UTF-8">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>文件上传</title>    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.0/dist/css/bootstrap.min.css"        integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">    <style>        img {            width: 100%;        }    </style></head><body>    <div class="container">        <div class="row">            <div class="col-md-6 m-auto">                <h3 class="text-center display-4 my-4">Mongo文件上传</h3>                <form action="/upload" method="POST" enctype="multipart/form-data">                    <div class="custom-file mb-3">                        <input type="file" name="file" id="file" class="custom-file-input">                        <label for="file" class="custom-file-label">选择文件</label>                    </div>                    <input class="btn btn-primary btn-block" type="submit" value="提交">                </form>                <hr>            </div>        </div>        <div class="row">            <% if(files){ %>            <% files.forEach(function(file){ %>            <div class="col-sm card card-body m-3  col-md-2">                <% if(file.isImage){ %>                <img class="lazy" data-src="image/<%= file.filename %>" />                <% } else { %>                <a href="download/<%= file.filename %>"><%= file.filename %></a>                <%}%>                    <form action="/files/<%= file._id%>?_method=DELETE" method="POST">                <button class="btn btn-danger btn-block mt-4">删除</button>                </form>            </div>            <% }) %>            <% }else { %>            <p class="card card-body text-center display-4 my-4">文件不存在</p>            <% } %>        </div>    </div></body><script class="lazy" data-src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js"    integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"    crossorigin="anonymous"></script><script class="lazy" data-src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"    integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"    crossorigin="anonymous"></script><script class="lazy" data-src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.0/dist/js/bootstrap.min.js"    integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI"    crossorigin="anonymous"></script></html>

要将 ejs 中的files变量获取到我们应该重写一下 get('/')接口,使其在访问localhost:5000的时候先去读取一下数据库文件信息并输出到页面中去

app.get('/', (req, res) => {gfs.files.find().toArray((err, files) => {if (!files || files.length === 0) {res.render('index', { files: false })return}files.map(file => {// 如果是以下图片类型我们就在前端展示出来,其余一律按附件处理,通过 isImage 来区分图片和非图片const imageType = ['image/png', 'image/jpg', 'image/gif', 'image/jpeg']if (imageType.includes(file.contentType)) {file.isImage = true} else {file.isImage = false}})res.render('index', { files: files })})})

3.7 单个文件下载

在这里我们通过a标签访问 /download/:filename 接口,filename是文件名,当然可以用其他的比如_id,当查找到有该附件的时候就将它合并成可读留,通过管道返回,这样在前端界面上点击文件标题就可以直接下载了

app.get('/download/:filename', (req, res) => {gfs.files.findOne({ filename: req.params.filename }, (err, file) => {if (!file) {return res.status(404).json({err: '文件不存在!'})}const readstream = gfs.createReadStream(file.filename)readstream.pipe(res)})})

3.8 单个文件删除

在这里我们通过a标签访问 /files/:id 接口,id对应,点击删除按钮,就直接删除了,并重定向到首页

app.delete('/files/:id', (req, res) => {gfs.remove({ _id: req.params.id, root: 'upload' }, (err) => {if (err) {return res.status(404).json({err: '删除的文件不存在!'})}res.redirect('/')})})

由于我们一直用form做请求,但是form表单没有delete请求方式,所以我们用到了method-override插件,当然要是用Ajax就没关系了,我们项目毕竟速成嘛,主要看效果和过程。

以上就是关于“如何使用Node和MongoDB搭建一个图床或网盘”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何使用Node和MongoDB搭建一个图床或网盘

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何使用Node和MongoDB搭建一个图床或网盘

这篇“如何使用Node和MongoDB搭建一个图床或网盘”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“如何使用Node和Mo
2023-06-27

如何使用node搭建一个小页面

这篇文章主要介绍“如何使用node搭建一个小页面”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“如何使用node搭建一个小页面”文章能帮助大家解决问题。完成展示首页详情页面前置知识首先我们需要了解一些
2023-07-04

如何使用php搭建一个简单的网站

创建动态PHP网站的完整指南本指南提供了分步说明,介绍如何使用PHP、HTML、CSS和MySQL/PostgreSQL构建动态网站。涵盖了从设置环境到处理表单输入、与数据库交互、实施安全措施和部署网站的各个步骤。还包括优化性能、管理依赖项和使用框架的附加提示,帮助您创建完整且功能强大的Web应用程序。
如何使用php搭建一个简单的网站
2024-04-08

如何使用php搭建一个简单的网站

要使用PHP搭建一个简单的网站,您可以按照以下步骤进行操作:1. 安装PHP:首先,您需要在您的计算机上安装PHP。您可以从PHP官方网站(https://www.php.net/downloads.php)下载PHP的最新版本,并按照官方
2023-08-24

如何使用python搭建一个高性能的网站

作为一名程序员,还是必须要会开发网站的,不然别人都会怀疑你是不是程序员了。今天,主要介绍一下如何使用python来搭建一个网站。可能有人会觉得搭建网站不都应该用java么?python的性能那么低。的确,使用java来开发网站的确要比pyt
2023-01-31

如何使用HTML和CSS创建一个响应式图片网格布局

如何使用HTML和CSS创建一个响应式图片网格布局在当今的互联网时代,图片占据了网络内容的重要一部分。为了展示各种类型的图片,我们需要一个有效且美观的网格布局。在本文中,我们将学习如何使用HTML和CSS创建一个响应式的图片网格布局。首先,
2023-10-27

使用SpringMVC和MyBatis框架如何搭建一个开发环境

本篇文章给大家分享的是有关使用SpringMVC和MyBatis框架如何搭建一个开发环境,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。1、下载SpringMVC框架架包,点击打
2023-05-31

如何使用HTML和CSS创建一个响应式图库布局

引言:随着移动设备的普及,响应式设计成为了网页设计的重要考虑因素之一。而在开发一个图库网站时,如何设计一个兼具美观和响应式布局的页面,将成为重要的问题。本文将详细讨论如何使用HTML和CSS来创建一个响应式图库布局,并且提供具体的代码示例。
2023-10-21

如何使用HTML和CSS创建一个网页侧边栏布局

首先,创建一个基本的HTML文档结构。在93f0f5c25f18dab9d176bd4f6de5d30e标签中,加入一个2cdf5bf648cf2f33323966d7f58a7f3f标签,引用一个外部CSS样式表文件。然后,在6c04bd
2023-10-21

如何使用HTML和CSS创建一个响应式图片墙布局

如何使用HTML和CSS创建一个响应式图片墙布局引言:随着移动互联网的普及,响应式设计成为了网页设计的重要标准。在网页设计中,图片墙布局是常见的一种布局形式,它可以以瀑布流的形式展示不同尺寸的图片。本文将介绍如何使用HTML和CSS创建一个
2023-10-25

如何使用HTML和CSS创建一个响应式轮播图布局

在现代的网页设计中,轮播图是一个常见的元素。它能够吸引用户的注意力,展示多个内容或图片,并且能够自动切换。在本文中,我们将介绍如何使用HTML和CSS创建一个响应式的轮播图布局。首先,我们需要创建一个基本的HTML结构,并添加所需的CSS样
2023-10-21

如何使用HTML和CSS创建一个响应式图片画廊布局

在现代的网页设计中,响应式设计已经成为一个非常重要的概念。随着移动设备的普及,人们对于在不同设备上浏览网页的需求也愈发增加。在本文中,我将详细介绍如何使用HTML和CSS创建一个响应式的图片画廊布局。首先,我们需要准备一些HTML结构来构建
2023-10-21

如何使用HTML和CSS创建一个响应式图片轮播布局

如何使用HTML和CSS创建一个响应式图片轮播布局在现代网页设计中,轮播图已经成为了很重要的元素之一。它可以有效地展示多张图片,并通过轮播的效果吸引用户的注意力。本文将介绍如何使用HTML和CSS来创建一个响应式图片轮播布局,并提供具体的代
2023-10-25

如何使用HTML和CSS创建一个响应式图标展示布局

随着移动设备的普及,响应式设计已经成为了网页设计的标准之一。在设计网页时,我们需要确保网页能够在不同尺寸的设备上展示良好,并且能够适应不同的屏幕大小。本文将介绍如何使用HTML和CSS来创建一个简单的响应式图标展示布局,并提供具体的代码示例
2023-10-21

如何使用HTML和CSS创建一个响应式图片滤镜布局

在今天的数字时代,网页设计变得越来越重要。而图片作为网页设计中的重要组成部分,扮演着非常重要的角色。为了使网页更具吸引力和魅力,我们经常使用图片滤镜来增强图片的效果。本文将介绍如何使用HTML和CSS创建一个响应式的图片滤镜布局,并提供具体
2023-10-21

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录