likes
comments
collection
share

node+express开发之上传文件

作者站长头像
站长
· 阅读数 23

文件上传是前后端交互必不可少的一个环节,今天我们就聊聊如何在nodeJs+express搭建的服务器中上传图片。本文讲述两种方法:formidable模块Muilter中间件,当然还有其他方法,如通过nodejs的文件流的方式,但本文不做概述。

下面是两种方法的基本使用,如果需要更复杂的功能可去查看官方文档formidable 以及multer

前提条件:

  • 前端:vue3 + element-plus
  • 后端:node + express
  • 使用express-generator生成项目

前端代码

node+express开发之上传文件

//javascript部分,使用axios
const handleAvatar = (file)=>{
//我们需要传给后端的是二进制流,element-plus上传组件的change事件传的参数是一个对象,其中的raw是我们需要的二进制对象
    let formData = new FormData()
      formData.append('file', file.raw)
    axios.post('/upload',formData).then(res=>{
        console.log(res)
    })
}

使用formidable模块

1、下载模块 npm i formidable

2、引入模块 const formidable = require("formidable")

3、开始使用

router.post("/upload", (req, res) => {
  const form = new formidable.IncomingForm();
  form.uploadDir = resolve("../public/images"); // 上传图片放置的文件夹
  form.options.keepExtensions = true; // 保持文件的原始扩展名
  //直接使用form.keepExtensions = true上传的文件不带扩展名
  form.parse(req, (err, fields, files) => {
  //parse: 解析request请求中包含的form表单提交的数据
  //files:传参中的上传文件二进制流对象
  //fields:传参中其他参数
    if (err) return;
    res.json({
      code: "0000",
      msg: "上传成功",
      data:`http://127.0.0.1:3031/images/${files.raw[0].newFilename}`,
    });
  });
});

文件上传成功后就可以在文件夹中看到上传的文件,但是这个文件名是随机生成的,如果想修改文件名,可以在parse()中,通过fs.rename()方法修改文件名称。 效果如下:

node+express开发之上传文件

使用中间件--muilter

Multer是一个node. js中间件,用于处理multipart/form-data,主要用于上传文件。Multer不会处理任何非multipart(multipart/form-data)的表单。更多方法请查看官方文档(multer

1、下载muilter npm i muilter --save

2、引入muilter const multer = require("multer");

3、使用中间件

const upload = multer({dest:'public/images'});
router.post("/upload", upload.single('file'), (req, res) => {
// req.file 包含上传文件信息的对象
// req.files是一个包含上传文件信息的数组
// req.body 上传参数中的其他参数信息
  res.json({
    code: "0000",
    msg: "上传成功",
    data:`/images/${req.file.originalname}`,
  });
});

muilter方法需传入一个对象,其中dest属性为文件上传后存储的位置

upload.single('file')中的file为前端发送请求时传参的属性名

执行代码后,会发现,在文件中多了个文件,但是没有后缀名,而且名称也是随机生成的,在实际开发中这样就有点不方便了,我们需要使用muilter的存储引擎,对文件做处理。

const multer = require("multer");
const storage = multer.diskStorage({
  //保存路径
  destination: function (req, file, cb) {
    cb(null,resolve("../public/images/"));
    //注意这里的文件路径,不是相对路径,直接填写从项目根路径开始写就行了
  },
  //保存在 destination 中的文件名
  filename: function (req, file, cb) {
    cb(null, file.originalname);
  },
});
const upload = multer({storage});

效果如下(带后缀名的是使用了存储引擎):

node+express开发之上传文件

报500错误

这里有个问题需要说明一下,上边提到了,muilter只处理multipart/form-data格式的数据,如果我们直接设置content-type:'multipart/form-data',不使用new FormData(),服务器会报500的错。 数据使用formData处理后,是否设置content-type值都可以,如果设置了,在请求头中content-type没有boundary值时(下图是有的情况),就删掉自己设置的content-type,浏览器会自动帮我们设置。

node+express开发之上传文件

前端页面展示图片

在文件上传时,我们将文件存储在public/images文件夹中,直接使用http://localhost:3000/public/images/文件名是访问不到的

在app.js文件中有这一行代码:

app.use(express.static(path.join(__dirname, "public")));

express.static 是express内置中间件函数,用来托管静态文件

express.static(root, [options]) //root参数指定为静态资产提供服务的根目录

我们在访问时,路径不需要加上public,路径为 http://localhost:3000/images/文件名

如果需要为静态文件创建虚拟路径前缀(文件系统中实际上不存在该路径),可以指定静态目录的挂载路径,如下所示

app.use('/static', express.static('public'))

访问路径就变成http://localhost:3000/static/images/文件名

转载自:https://juejin.cn/post/7397669215732564022
评论
请登录