Mongoose应用和文件文件的上传和下载

news2024/9/19 12:01:55

一、Express框架访问MongoDB数据库

1、目的:

​ (1)mongoose模块的使用

​ (2)学会代码的封装:dao层、service层、接口层

​ (3)MVC设计思想:M(Model)、V(View)、C(Controller)

2、设计思路:

​ (1)数据库:blog集合(blogId、title、content、type、author、createAt)

​ (2)创建Dao层:创建Schema —-> 创建模型Model —-> 操作数据库中的blog集合

​ (3)创建Service层:调用dao层访问数据库、接收客户端的数据、把处理的结果响应给客户端

​ (4)创建接口层:路由接口(路由中间件)

​ (5)测试接口

​ (6)创建前端页面

​ (7)实现blogId的自增

3、代码实现

​ (1)创建Express项目:确定端口号、跨域的设置、代码更新能自动重启

​ (2)项目目录结构的设置:

        ​ dao(config、model、crud)

        ​ service

​ (3)安装mongoose、定义配置文件(连接数据库)

 

二、node实现文件上传

1、FormData对象:

以对象的方式来表示页面中的表单,又称为表单对象。以key-value的方式来保存数据,XMLHttpRequest对象可以轻松的表单对象发送的服务器端

​ (1)是一个构造函数:new FormData(),例如:

var  formdata = new FormData(form)  //将页面中的表单form转换成FormData对象(即将表单数据转换成key-value对)

(2)常用的API:

        ​ FormData.append(key,value):追加数据。向formdata中追加key-value

        ​ FormData.get(key):获取key对应的值

        ​ FormData.delete(key):删除key对应的值

        ​ FormData.has(key):判断formdata中是否有key

2、node使用formidable模块实现文件上传

​ (1)安装:npm install formidable

​ (2)创建Formidable.IncomingForm对象:本质是一个表单对象

                ​ let form = new Formidable.IncomingForm()

​ (3)Formidable.IncomingForm对象的属性:

         form.encoding : 设置字符集

        ​ form.uploadDir:设置上传文件的保存路径

        ​ form.keepExtensions:true,表示上传时保留原来的扩展名

​ (4)Formidable.IncomingForm对象的方法:

        ​ form.parse(request, [callback]):转换请求中的表单数据

​ (5)Formidable.File对象的属性

        ​ size:上传文件的大小

        ​ path:上传文件的路径

        ​ type:上传文件的类型

        ​ name:上传的文件名

3、示例:

​ (1)前端:

<body>
    <!-- 
        上传图片步骤:
            1.将图片文件上传到服务器端的指定目录
            2.将图片文件名和服务器的地址进行拼接
            3.将拼接后的图片的路径响应给客户端,在div中显示出来
     -->

    <label for="">
        请选择文件:
        <input type="file" id="file" />
    </label>
    <br /><br />
    <div id="box"></div>
    <script>
        $(function () {
            // 创建formdata对象
            let formdata = new FormData();
            // 给file控件绑定change事件
            $("#file").change(function () {
                //1.获取input中得到的文件名
                if ($("#file").val().length) {
                    //如果用户选择了文件
                    // 获取文件名
                    let fileName = $("#file").val();
                    // 获取文件的后缀---扩展名,并将其转换成小写
                    let extenName = fileName.substring(fileName.lastIndexOf("."), fileName.length).toLowerCase();
                    // 判断文件类型
                    if (extenName === ".jpg" || extenName === ".png") {
                        // 追加
                        formdata.append("uploadFile", $("#file")[0].files[0]);
                    } else {
                        alert("文件格式不正确");
                    }
                }

                //2.向服务器发起上传请求
                $.ajax({
                    url: "http://127.0.0.1:3000/updown/upload",
                    type: "post",
                    data: formdata,
                    cache: false, //上传时文件不缓存
                    contentType: false, //jQuery不能设置请求头中的contentType
                    processData: false, //jQuery不能处理上传的数据
                    success: function (result) {
                        let img = document.createElement("img");
                        img.style.width = 420 + "px";
                        img.style.height = 260 + "px";
                        img.src = result.path; //path表示是服务器的响应的图片的访问路径
                        $("img").remove(); //有新图片显示时,将原图片删除
                        $("#box").append(img);
                    },
                    error: function (err) {
                        console.log(err);
                    }
                });
            });
        });
    </script>
</body>

 (2)后台(上传-下载服务器)

//上传接口:http://localhost:8089/updown/upload
router.post('/upload',(req, res) => {
      // 1.设置上传文件的保存路径:上传文件夹
    let cacheFolder = 'public/images/uploads'
      // 2.判断上传文件夹是否存在,若不存在则创建
    if (!fs.existsSync(cacheFolder)){ //同步判断
        fs.mkdirSync(cacheFolder) //同步创建
    }
      // 3. 创建form对象接收客户端的formdata中的数据:使用formidable模块的IncomingForm
    let form = new formidable.IncomingForm()
    form.encoding = 'utf-8' //设置表单域的字符集
    form.uploadDir = cacheFolder //设置上传目录
    form.keepExtensions = true //保留上传文件的后缀
    form.maxFieldsSize = 2 * 1024 * 1024 // 1K=1024B   1M=1024K
    form.type = true //上传文件的类型为只读
      // 4.接收上传文件并进行处理
    let displayUrl; //上传的文件在服务器端的访问路径
    form.parse(req,function (err,fields,files){ //files是前端的formdata对象
        if (err){ //表示上传错误
            res.send(err)
            return
        }
        let extName='' //存放上传文件的后缀(扩展名)
        switch(files.uploadFile.mimetype){ //uploadFile对应的是前端formdata中的key,mimetype表示上传文件的类型
            case 'image/jpg':
                extName = '.jpg'
                break
            case 'image/jpeg':
                extName = '.jpg'
                break
            case 'image/png':
                extName = '.png'
                break
        }
        //5. 对上传文件的后缀进行处理
        if(extName.length == 0){
            res.send({
                code: 202,
                msg: '只能上传jpg和png格式的文件'
            })
        }else{ //符合上传要求的文件
           // 5.1 将上传文件和上传的文件名进行拼接
            let savePath = form.uploadDir + '/'+ files.uploadFile.originalFilename //originalFilename表示上传文件的原名
            displayUrl = `http://localhost:8089/images/uploads/${files.uploadFile.originalFilename}`
            //5.2 对文件重命名
            //files.uploadFile.filepath : C:\fakepath\2.png
            //savePath:D:\woniu\Web前端11期\12-2\demo\up-down\public\images\uploads\2.png
            fs.renameSync(files.uploadFile.filepath,savePath) //用savePath替换filePath,方法必须是同步方法
            res.json({
                code: 202,
                path: displayUrl
            })
        }
    })
})

4、文件上传需要注意的问题

​ (1)前端FormData对象作用:用于保存上传文件的信息。格式:key-value

​ (2)后台formidable模块的作用:使用parse方法来解析前端的formdata对象

 ​ (3)上传过程中前后端的对应关系

三、Express实现文件下载

1、使用res对象(响应对象)的download方法即可

四、遍历下载文件夹下的文件,拼接成一个下载的url,传递到前端

后台接口:

// 遍历下载文件夹的接口:http://localhost:8089/updown/getfiles
router.get('/getfiles',(req, res) => {
    //1.遍历下载文件夹:public/images/uploads
    let filePath = path.join(__dirname,'../../public/images/uploads/') //下载文件夹
    let url_arr = [] //存放下载的url
    fs.readdir(filePath,(err,files)=>{ //files参数中存放的filePath下的子目录名和文件名
        if (err){
            console.log(err)
        }else{
            for(let i=0;i<files.length;i++){
                let fileDir = path.join(filePath,files[i])
                if (fs.statSync(fileDir).isFile()){ //表示当前的files[i]是一个文件
                    let urlObj = {
                        fileName: files[i],  //文件名
                        downloadUrl: `http://localhost:8089/updown/download?fileName=${files[i]}`
                    }
                    url_arr.push(urlObj) //把要下载的文件路径、文件放入数组中
                }
            }
            res.json(url_arr)
        }
    })
})

 前端页面:

<body>
    <div id="box"></div>
    <script src="./js/jquery-3.4.1.js"></script>
    <script>
        $(function(){
            $.ajax({
                url: 'http://localhost:8089/updown/getfiles',
                type:'get',
                dataType:'json',
                success: function(result){
                    for(let data of result){
                        $('#box').append(`<a href=${data.downloadUrl}>下载${data.fileName}</a>`)
                                 .append('<br><br>')
                    }
                }
            })
        })
    </script>
</body>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]Python计算机毕业设计Django基于SpringBoot的演唱会购票系统论文2022

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;我…

c#与mysql连接和操作教程(增、删、改、查)

一、mysql的连接&#xff08;使用的是vs2019&#xff09; 1. 在一个项目中选择 工具 > NgtGet包管理器 > 管理解决方案的NuGet程序包 2. 搜索MySql.Data&#xff0c;然后下载&#xff0c;并在右边选着对应的项目进行安装&#xff08;ps&#xff1a;每个项目要连接数据库…

【身份证识别】基于BP神经网络实现身份证识别附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

代码随想录刷题|LeetCode 300.最长递增子序列 674. 最长连续递增序列 718. 最长重复子数组

目录 300.最长递增子序列 思路 1、dp[i]的定义 2、递推公式 3、dp数组初始化 4、确定遍历顺序 5、推导dp数组 最长递增子序列 674. 最长连续递增序列 思路 最长连续递增序列 动态规划 贪心算法 718. 最长重复子数组 思路 1、确定dp数组的含义 2、确定递推公式 3、dp数组初始化…

docker 命令

目录 Docker 环境信息命令 docker info docker version 系统日志信息常用命令 docker events docker logs docker history 容器的生命周期管理命令 docker create docker run 常用选项 系统 网络 健康检查 命名空间选项 cgroup资源限制选项 CPU CPUset devi…

李宏毅《DLHLP》学习笔记7 - Voice Conversion 1

视频链接&#xff1a;https://www.youtube.com/watch?vJj6blc8UijY&listPLJV_el3uVTsO07RpBYFsXg-bN5Lu0nhdG&index9&ab_channelHung-yiLee 课件链接&#xff1a;https://speech.ee.ntu.edu.tw/~tlkagk/courses/DLHLP20/Voice%20Conversion%20(v3).pdf 1. 语音转…

永磁同步电机恒压频比(V/F)开环控制系统Matlab/Simulink仿真分析及代码生成到工程实现(二)

文章目录前言一、SVPWM二、永磁同步电机恒压频比开环控制系统Matlab/Simulink仿真分析2.1.仿真电路分析2.1.1.恒压频比控制算法2.1.2.输出处理2.1.3.主电路2.2.仿真结果分析三、永磁同步电机恒压频比开环控制系统代码生成及工程实现3.1.恒压频比开环控制算法代码生成3.2.仿真验…

计算机毕业论文Java项目源码下载基于SSM的旅游资讯网站含前台与后台

&#x1f496;&#x1f496;更多项目资源&#xff0c;最下方联系我们✨✨✨✨✨✨ 目录 Java项目介绍 资料获取 Java项目介绍 《ssm地方旅游资讯网站》该项目采用技术&#xff1a;jsp 、springmvc、spring、mybatis 、css、js、jQuery、bootstrap、easyui等相关技术&#x…

在云服务器上部署jupyter服务器环境(with conda-forge)

tags: Python Conda Tips Server 写在前面 最近想折腾点服务器的新花样(总是空着太可惜了), 想到前阶段配置的jupyter, 发现这不就能部署在服务端吗?还不走流量的那种(指安装包时候), 话不多说, 开整! 下面的用户名以及组都是test, 用于测试. 大家需要改成自己的用户名. 安装…

【Nginx】负载均衡、动静分离理论篇

一、负载均衡 1. 应用场景&#xff1a; 2. 负载均衡是什么&#xff1f; 在当业务系统服务器无法支撑当前的业务量时&#xff0c;用户可以选择更高性能的服务器。 但更为合理的做法是通过在既有业务服务器基础上&#xff0c;增量的方式增加相同功能的服务器&#xff0c;将处理…

Linux操作系统(基础操作)

文章目录一、文件操作命令1. 目录和文件操作2. 查看文件内容3. 重定向4. 管道二、信息系统相关命令1. 查看系统进程 -- ps2. 查看系统监听端口 -- netstat3. 查看日志信息命令 -- head / tail三、用户权限和管理1. linux中的权限2.修改用户权限chmod3.增加用户、查看登录用户4.…

CAS-比较并交换

CAS-比较并交换 原子类 何为原子类 没有CAS之前 多线程环境不使用原子类保证线程安全i&#xff08;基本数据类型&#xff09; 常用synchronized锁&#xff0c;但是它比较重 &#xff0c;牵扯到了用户态和内核态的切换,效率不高。 public class T3 {volatile int number 0…

JMeter 进行函数助手MD5加密

JMeter 函数助手 MD5 加密 JMeter函数助手中&#xff0c;提供了MD5加密的方法&#xff0c;如图所示&#xff0c;我们将内容 “123456”进行加密&#xff0c;可以看到加密成功了。 下面我们来看看项目接口的请求参数。 这是一个认证接口&#xff0c;我们可以看到请求的参数中包…

MySQL-MVCC多版本控制及事务的隔离性

MySQL事务的启动方式 隐式&#xff1a;执行SQL语句自动提交&#xff08;前提MySQL使用SET AUTOCOMMIT1开启自动提交&#xff09;显式&#xff1a;begin/start transaction; update user set username timi where id 1; commit; begin/start transaction命令并不是一个事务的起…

UE获取当前鼠标点击位置坐标

文章目录 1. 实现目标2. 实现过程2.1 蓝图代码2.2 实现思路3. 参考资料1. 实现目标 获取当前鼠标点击位置的UE世界坐标(x,y,z),效果如下图所示(为便于演示,下图显示了碰撞点位)。 2. 实现过程 2.1 蓝图代码 (1)核心函数的蓝图代码如下: (2)当鼠标左键按下时,…

【✨十五天搞定电工基础】一阶电路的暂态分析

本章要求1. 了解电阻元件、电感元件与电容元件的特征; 2. 理解电路的暂态和稳态、零输入响应、零状态响应、全响应的概念&#xff0c;以及时间常数的物 理意义; 3. 掌握换路定则及初始值的求法; 4. 掌握一阶线性电路分析的三要素法。 目录 一、一阶电路和换路定律 1…

第十四章 图的存储及图的DFS(超级详细!!逐行解析!!)

第十四章 图的存储及图的DFS一、图1、什么是图&#xff1f;2、图的存储&#xff08;1&#xff09;邻接矩阵&#xff08;2&#xff09;邻接表二、图的深度优先搜索1、思路2、模板&#xff08;1&#xff09;问题&#xff1a;如何求左右子树呢?什么时候记录呢&#xff1f;如何构造…

数字孪生场景、代码即开即用 | 图观™引擎 超详细功能范例演示

数字孪生已经从一项前沿技术&#xff0c;演变成为各行各业数字化转型的必选项。 过去想要构建数字孪生应用&#xff0c;要面对视觉设计、三维底座构建、代码开发、数据对接、部署联调等一系列复杂工作。不仅要了解复杂的数学基础知识、底层三维开发技术&#xff0c;还要熟知各…

Spring Cloud微服务迁移到Kubernetes容器化

文章目录相关文章k8s容器部署流程熟悉Spring Cloud微服务项目源代码编译构建构建项目镜像并推送到镜像仓库制作镜像将镜像推送到harbor仓库K8s服务编排部署基础环境在K8s中部署Nacos集群&#xff08;注册和配置中心&#xff09;在k8s中部署Seata分布式事务在linux部署mysql,red…

李炎恢ECMAScript6 / ES6+(二)

16.Set 数据集合 学习要点&#xff1a; 1.Set 数据集合 本节课我们来开始学习 ES6 新增的 Set 数据集合的用法&#xff1b; 一&#xff0e;Set 数据集合 1.ES6 之前只有数组一种数据结构&#xff0c;而现在提供了 Set 和 Map 两种集合&#xff1b; 严格来说&#xff0c;对象…