node实现文件上传和下载

news2024/12/23 14:14:34

一、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>请选择文件:
        <input type="file" id="file">
    </label>
    <br><br>
    <div id="box">div</div>
    <script>
        $(function(){
            //给file控件绑定change事件
            $('#file').change(function(){
                //1. 获取input中得到的文件名
                if($('#file').val().length){ //如果用户选择了文件
                    let fileName = $('#file').val()  //获取文件名
                    console.log(fileName)
                    //获取文件的后缀(扩展名),并把后缀名转换成小写
                    let extenName = fileName.substring(fileName.lastIndexOf('.'),fileName.length).toLowerCase()
                    if(extenName==='.jpg' || extenName==='.png'){ //若文件是图片
                        let  formdata =  new FormData() //创建表单对象
                        console.log($('#file')[0])
                        console.log($('#file')[0].files[0])
                        formdata.append('uploadFile',$('#file')[0].files[0])
                    }else{
                        alert('文件格式错误')
                    }
                }
                // 2.向服务器发起上传请求
                $.ajax({
                    url:'http://localhost:8089/upload',
                    type: 'post',
                    data: formdata,
                    cache: false,//上传时文件不缓存
                    contentType: false, //jQuery不能设置请求头中的contentType ,必须的设置
                    processData: false, //jQuery不能处理上传的数据,必须配置
                    success: function(result){
                        // 2.1 创建一个img标签
                        let img = document.createElement('img')
                        // 2.2 设置img标签的样式
                        img.style.width = 350+'px'
                        img.style.height = 280+'px'
                        // 2.3 设置img标签的src属性
                        img.src = result.path  //path:表示是服务器响应的图片的访问路径
                        // 2.4 显示的设置
                        $('img').remove() //有新图片显示时,将原图片删除
                        // 2.5 将img标签添加到div中
                        $('#box').append(img)
                    },
                    error: function(error){ //请求-响应失败后的处理代码
                        console.log(error)
                    }
                })
            })
        })
    </script>
</body>

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

//上传接口: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实现文件下载 

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

 下载接口:

//下载接口:http://127.0.0.1:8089/updown/download
router.get('/download',(req,res)=>{
   try{
       //使用parse模块对客户端请求下载的文件路径进行拼接
       //__dirname:全局属性,代表的是当前文件的绝对路径
       let filePath = path.join(__dirname,'../public/images/uploads/' + req.query.fileName)
       console.log(__dirname)
       res.download(filePath)
   }catch (e) {
       console.log(e)
   }
})

前端:

    <a href="http://127.0.0.1:8089/updown/download?fileName=2.png">下载2.png</a>
    <a href="http://127.0.0.1:8089/updown/download?fileName=abc.txt">下载abc.txt</a>

三、遍历下载文件夹下的文件

        遍历下载文件夹下的文件,拼接成一个下载的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/138813.html

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

相关文章

Talk预告 | 字节跳动(北美)软件工程师桑燊:风格化3D虚拟形象的创建

本期为TechBeat人工智能社区第469期线上Talk&#xff01; 北京时间1月5日(周四)20:00&#xff0c;字节跳动(北美) 计算机视觉与图形学软件工程师——桑燊的Talk将准时在TechBeat人工智能社区开播&#xff01; 他与大家分享的主题是: “风格化3D虚拟形象的创建”&#xff0c;届时…

mongodb 分组子文档合并

【问题】Hi, i am trying to use mongodb aggregate query using $setUnion, $project and also $group to group the documents. The structure of document is{ “_id” : ObjectId(“55014006e4b0333c9531043e”), “acls” : { “append” : { “users” : [ObjectId(“54f…

domain_fronting域名前置检测调研笔记

暗度陈仓&#xff1a;基于国内某云的 Domain Fronting 技术实践 https://www.anquanke.com/post/id/195011?fromtimeline 1.作者提到因为 CDN 的存在&#xff0c;访问网站时访问的实际上只是 CDN&#xff0c;而不是直接和网站的真实服务器进行通信&#xff0c;所以利用 CDN 的…

【虹科云展厅】虹科赋能汽车智能化云展厅今日正式上线!

虹科2023年开年福利来了&#xff01; 聚焦前沿技术&#xff0c;【虹科赋能汽车智能化云展厅】正式上线&#xff0c;本次云展厅围绕“汽车以太网/TSN、汽车总线、智能网联、电子测试与验证、自动驾驶”等核心话题&#xff0c;为您带来如临展会现场般的讲演与介绍&#xff0c;更…

【MySQL】MySQL基本数据类型

序号系列文章1【MySQL】MySQL介绍及安装2【MySQL】MySQL基本操作详解3【MySQL】MySQL基本数据类型文章目录1&#xff0c;数字类型1.1&#xff0c;整型类型1.2&#xff0c;浮点数类型1.3&#xff0c;定点数类型1.4&#xff0c;BIT类型1.5&#xff0c;直接常量2&#xff0c;时间和…

2024在职考研|MBA/MPA/MEM管理类硕士报考流程及基础问题扫盲

各位小伙伴们&#xff0c;2024年研究生备考工作即将启程&#xff01;作为在职人群&#xff0c;想攻读双证硕士可以选择的专业比较有限&#xff0c;其中管理类硕士是很多在职考生可以考虑的。专注管理类联考辅导领域的达立易考教育为2024级考生梳理基本流程和关注的问题&#xf…

举一反三-zabbix监控nginx

监控nginx需要修改nginx配置文件&#xff0c;添加如下&#xff1a; location /nginx_status { stub_status; allow 127.0.0.1; allow 192.168.1.71; deny all; } 这里边192.168.1.71是这台服务器的IP。 保存退出&#xff0c;重启…

【阶段二】Python数据分析Pandas工具使用06篇:探索性数据分析:异常数据的检测与处理

本篇的思维导图: 探索性数据分析:异常数据的检测与处理 异常值也称为离群点,就是那些远离绝大多数样本点的特殊群体,通常这样的数据点在数据集中都表现出不合理的特性。如果忽视这些异常值,在某些建模场景下就会导致结论的错误(如线性回归模型、K均值聚类等),所以在数据…

《杜拉拉升职记》读后感

主要是那封拉拉写给李都的信&#xff0c;内容&#xff1a;一、关于什么样的职位算好职位1.你的找一家好公司&#xff0c;什么是好公司?1)产品附加值高&#xff0c;生意好&#xff0c;并且从业务线看&#xff0c;具备持续发展的能力和前景;2)有专业的/聪明能干的/经验丰富的/并…

ESP IDF:创建并打印vector的元素值

ESP IDF:创建并打印vector的元素值 程序&#xff1a; #include <stdio.h> #include std::vector v; std::vector::iterator pBegin v.begin(); std::vector::iterator pEnd v.end(); void test_vector() { v.push_back(10); v.push_back(20); v.push_back(30); v.…

iPhone 14微信闪退怎么办?iPhone 14微信闪退解决办法分享

大家在iPhone上使用微信的时候肯定都有遇到过微信闪退的情况&#xff0c;闪退问题一旦出现&#xff0c;就会严重影响我们的正常使用&#xff0c;特别是使用频繁的APP。 iPhone 14微信闪退是什么原因造成的&#xff1f;iPhone 14微信闪退怎么办&#xff1f; 一、缓存垃圾过多 …

Qt扫盲-QLinkedList理论总结

QLinkedList理论总结一、概述二、使用说明1. 声明链表2. 获取元素、链表信息3. 删除元素4. 添加元素5. 遍历元素一、概述 QLinkedList是Qt的泛型容器类之一。它存储一个值列表&#xff0c;并提供基于迭代器的访问以及常量时间的插入和删除。 QList、QLinkedList和QVector提供类…

JavaScript刷LeetCode模板技巧篇(一)

虽然很多人都觉得前端算法弱&#xff0c;但其实 JavaScript 也可以刷题啊&#xff01;最近两个月断断续续刷完了 leetcode 前 200 的 middle hard &#xff0c;总结了一些刷题常用的模板代码。 常用函数 包括打印函数和一些数学函数。 const _max Math.max.bind(Math); co…

【C++】stack和queue

文章目录前言&#xff08;重点&#xff09;一、stack1、 stack的介绍2、queue的使用3、stack的模拟实现二、queue1、queue的介绍2、queue的使用3、queue的模拟实现三、容器适配器1、什么是容器适配器呢&#xff1f;2、STL标准库中stack和queue的底层结构四、deque1、deque的原理…

设计模式之单例模式(懒汉, 饿汉)

文章目录一. 单例模式概述二. 单例模式的实现1. 饿汉模式2. 懒汉模式一. 单例模式概述 单例模式是一种常用的软件设计模式, 该模式的主要目的是确保某一个类在内存中只能有一个实例对象, 通过单例模式的方法创建的类在当前进程中只有一个实例对象. 常见的单例模式有两种: 饿…

制作系统安装(微软操作系统系统)

系统安装制作步骤 准备工具&#xff1a;笔记本电脑 8G以上u盘 镜像ISO文件 微软系统下载&#xff1a;https://msdn.itellyou.cn/ 复制连接到迅雷下载&#xff0c;进行系统镜像下载。 U盘制作工具下载和制作&#xff1a; 制作工具网站下载&#xff1a;http://rufus.ie/zh/ 准…

MySQL避免插入重复数据

新建一张测试表&#xff0c;有三个字段&#xff0c;自增主键id、创建了唯一索引的user_name、以及普通字段address。然后插入一条数据作为原始数据&#xff0c;如下所示 1、insert ignore into 基于索引字段数据进行判断&#xff0c;如果索引数据存在&#xff0c;那么忽略本…

CSS单行/多行文本溢出隐藏

前言 在日常开发展示页面&#xff0c;如果一段文本的数量过长&#xff0c;受制于元素宽度的因素&#xff0c;有可能不能完全显示&#xff0c;为了提高用户的使用体验&#xff0c;这个时候就需要我们把溢出的文本显示成省略号 对于文本的溢出&#xff0c;我们可以分成两种形式…

jetson nano安装远程桌面,Qt,pytorch,tensorflow,virtualenv等

文章目录基于jetPack版本4.6.1一.基础组件配置检查二.基础组件安装1.安装pip32.安装python-opencv与机器学习常用包3.安装pytorch方法1&#xff08;失败&#xff09;方法2&#xff08;成功&#xff09;4.安装tensorflow-gpu5.安装QT6.板载摄像头使用7.安装中文输入法8.安装截图…

网络爬虫入门到实战

简介 数据采集文章 开始 入门程序 环境准备 pip3 install beautifulsoup4 基本操作 from urllib.request import urlopen from bs4 import BeautifulSouphtml urlopen("http://www.baidu.com") # print(html.read()) (打印html完整内容) bsObj BeautifulSou…