91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用Node和MongoDB搭建一個圖床或網盤

發布時間:2022-02-25 16:05:39 來源:億速云 閱讀:229 作者:iii 欄目:開發技術

這篇“如何使用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 // or yarn 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 = 5000
app.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 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 src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script 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 中間件來講我們上傳的附件直接存儲到MongoDb
const 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 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 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 src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
    integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
    crossorigin="anonymous"></script>
<script 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搭建一個圖床或網盤”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

青冈县| 双桥区| 绩溪县| 开化县| 岑溪市| 琼中| 丽水市| 绍兴县| 泰安市| 集贤县| 石景山区| 内江市| 连江县| 高清| 获嘉县| 岫岩| 商水县| 彰化县| 临朐县| 奉新县| 屏东市| 北宁市| 田林县| 墨竹工卡县| 公主岭市| 夏津县| 余庆县| 宝鸡市| 三都| 台南市| 丰宁| 卓尼县| 麟游县| 镇雄县| 邻水| 来凤县| 长丰县| 奈曼旗| 高碑店市| 永靖县| 铅山县|