• 【node进阶】Express+Multer+Postman模拟文件上传功能


    ✅ 作者简介:一名普通本科大三的学生,致力于提高前端开发能力
    ✨ 个人主页:前端小白在前进的主页
    🔥 系列专栏 : node.js学习专栏
    ⭐️ 个人社区 : 个人交流社区
    🍀 学习格言: ☀️ 打不倒你的会使你更强!☀️
    💯 刷题网站:这段时间有许多的小伙伴在问有没有什么好的刷题网站,博主在这里给大家推荐一款刷题网站:👉点击访问牛客网👈牛客网支持多种编程语言的学习,各大互联网大厂面试真题,从基础到拔高,快来体验一下吧!


    在这里插入图片描述


    🔥前言

    在我们开发中,如果想上传文件,或者做个人中心的头像的时候不会再向我们之前那样仅仅发送一个post请求了,会指定相应的配置,以及需要搭配一个中间件Multer,接下来将详细展开!

    Multer中间件

    Multer 是一个 node.js 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件。
    注意: Multer 不会处理任何非 multipart/form-data 类型的表单数据

    文件上传不同于我们传给后端普通的键值对,一般情况下我们所传的类型是x-www-form-urlencoded,但是官方规定文件上传的类型是multipart/form-data,我们如果自己去处理multipart/form-data类型的数据时,非常的吃力,于是借助于Multer中间件很好的解决了文件上传的问题。


    安装Multer

    npm install --save multer
    
    • 1

    基本使用方法

    const express = require('express')
    const multer  = require('multer')
    const upload = multer({ dest: 'uploads/' })
    
    const app = express()
    
    app.post('/profile', upload.single('avatar'), function (req, res, next) {
      // req.file 是 `avatar` 文件的信息
      // req.body 将具有文本域数据,如果存在的话
    })
    
    app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
      // req.files 是 `photos` 文件数组的信息
      // req.body 将具有文本域数据,如果存在的话
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    常用API解析

    multer(opts)

    Multer 接受一个 options 对象,其中最基本的是 dest 属性,这将告诉 Multer 将上传文件保存在哪。如果你省略 options 对象,这些文件将保存在内存中,永远不会写入磁盘

    为了避免命名冲突,Multer 会修改上传的文件名。这个重命名功能可以根据您的需要定制。

    以下是可以传递给 Multer 的选项:

    描述
    dest or storage在哪里存储文件
    fileFilter文件过滤器,控制哪些文件可以被接受
    limits限制上传的数据
    preservePath保存包含文件名的完整文件路径

    通常,一般的网页应用,只需要设置 dest 属性,像这样:

    const upload = multer({ dest: 'uploads/' })
    
    • 1

    如果你想在上传时进行更多的控制,你可以使用 storage 选项替代 dest。Multer 具有 DiskStorage 和 MemoryStorage 两个存储引擎;另外还可以从第三方获得更多可用的引擎。

    .single(fieldname)

    接受一个以 fieldname 命名的文件。这个文件的信息保存在 req.file


    .array(fieldname[, maxCount])

    接受一个以 fieldname 命名的文件数组。可以配置 maxCount 来限制上传的最大数量。这些文件的信息保存在 req.files


    storage

    在这里就先给大家讲述一个存储引擎(磁盘存储引擎 (DiskStorage)),另外一个大家可以去github官网自行学习,不要问我为什么,因为在这里只用了第一种(哈哈哈哈)

    磁盘存储引擎可以让你控制文件的存储

    const storage = multer.diskStorage({
      destination: function (req, file, cb) {
        cb(null, '/tmp/my-uploads')
      },
      filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
      }
    })
    
    const upload = multer({ storage: storage })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    有两个选项可用,destinationfilename。他们都是用来确定文件存储位置的函数

    destination 是用来确定上传的文件应该存储在哪个文件夹中。也可以提供一个 string (例如 ‘/tmp/uploads’)。如果没有设置 destination,则使用操作系统默认的临时文件夹

    注意: 如果你提供的 destination 是一个函数,你需要负责创建文件夹当提供一个字符串,multer 将确保这个文件夹是你创建的

    filename 用于确定文件夹中的文件名的确定。 如果没有设置 filename,每个文件将设置为一个随机文件名,并且是没有扩展名的。

    注意: Multer 不会为你添加任何扩展名,你的程序应该返回一个完整的文件名

    每个函数都传递了请求对象 (req) 和一些关于这个文件的信息 (file),有助于你的决定。

    注意 : req.body 可能还没有完全填充,这取决于向客户端发送字段和文件到服务器的顺序。

    警告: 确保你总是处理了用户的文件上传。 永远不要将 multer 作为全局中间件使用,因为恶意用户可以上传文件到一个你没有预料到的路由,应该只在你需要处理上传文件的路由上使用。

    这里是将官网中的话迁移了过来(Multer的官方解释链接),因为我觉得官网讲的已经通俗易懂了,没必要再去白话文化了,在这里已经把我们要用的multer主要的部分讲解了,接下来将进行文件上传功能


    文件上传功能实现

    demo目录架构

    在这里插入图片描述


    入口文件(app.js)

    const express = require('express')
    const app = express()
    const uploadRouter = require('./index')
    //想要在前端页面中访问到图片,去挂载静态资源
    app.use(express.static('./public'))
    //给路由挂载一个前缀
    app.use('/api',uploadRouter)
    app.listen(8080,()=>{
        console.log('8080端口已启动...');
    })  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    路由文件

    const express = require('express')
    //引入path模块的目的在于获取文件后缀名
    const path = require('path')
    const multer = require('multer')
    const router = express.Router()
    //进行自定义储存,并且将后端返回的文件加上后缀名后储存到文件夹中
    const storage = multer.diskStorage({
        destination: function (req, file, cb) {
          //在这里第二个参数传递了我们指定创建的储存文件的文件夹
          cb(null, 'public/uploads')
        },
        filename: function (req, file, cb) {
            //path模块获取文件后缀
            let ext = path.extname(file.originalname)
            //根据时间戳生成文件名字
            cb(null,Date.now() + ext)
        }
      })
      //在这里告诉Multer文件保存到了指定位置
      const upload = multer({ storage: storage })
    router.post('/upload',upload.single('avater'),(req,res)=>{
    	console.log(req.file)
    	//将文件拼接成url地址,通过浏览器进行访问文件
        res.send({
            msg: '图片上传成功',
            url : `http://localhost:8080/uploads/${req.file.filename}`
        })
    })
    
    module.exports = router
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    我们在这里打印了req.file,具体解析如下图:
    在这里插入图片描述


    Postman测试

    在这里插入图片描述


    最终实现效果

    在这里插入图片描述


    补充

    本篇文章中并没有给大家结合html来给大家做一个前端的演示,但是实现的原理是一样的,前端通过form表单或者FormData发送请求。
    如果你是form表单直接提交,不要忘记在form添加属性enctype="multipart/form-data",
    如果你是通过FormData发送请求,不要忘记进行一些配置(这里的代码只是为了告诉你怎么去做,不要直接cv,要不然没有效果):

    const formdata = new FormData()
    formdata.append('avater', avater.files[0])
    const config = {
        headers: {
            "Content-Type":"multipart/form-data"
        }
    }
    router.post('/api/upload', formdata, config).then(res => {
        this.imgpath = 'http://localhost:8080' + res.data
    })    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

  • 相关阅读:
    MobaXterm 突破14个session限制
    安全渗透测试之信息收集
    Elastic Search 7.x 学习笔记
    小试牛刀-Telebot区块链游戏机器人
    头歌-信息安全技术-用Python实现自己的区块链、支持以太坊的云笔记服务器端开发、编写并测试用于保存云笔记的智能合约、支持以太坊的云笔记小程序开发基础
    干货!英语常用口语1000句大全(完整版)!
    小学生写作业用什么灯最好?分享学生专用的暖光LED灯
    springboot里整合pmd
    go基础语法50问,来看看你的go基础合格了吗?
    leaflet 地图遮罩、扣洞
  • 原文地址:https://blog.csdn.net/m0_52040370/article/details/127580811