node+express开发之上传文件
文件上传是前后端交互必不可少的一个环节,今天我们就聊聊如何在nodeJs+express搭建的服务器中上传图片。本文讲述两种方法:formidable模块 和 Muilter中间件,当然还有其他方法,如通过nodejs的文件流的方式,但本文不做概述。
下面是两种方法的基本使用,如果需要更复杂的功能可去查看官方文档formidable 以及multer
前提条件:
- 前端:vue3 + element-plus
- 后端:node + express
- 使用express-generator生成项目
前端代码:
//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()方法修改文件名称。 效果如下:
使用中间件--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});
效果如下(带后缀名的是使用了存储引擎):
报500错误
这里有个问题需要说明一下,上边提到了,muilter只处理multipart/form-data格式的数据,如果我们直接设置content-type:'multipart/form-data',不使用new FormData(),服务器会报500的错。 数据使用formData处理后,是否设置content-type值都可以,如果设置了,在请求头中content-type没有boundary值时(下图是有的情况),就删掉自己设置的content-type,浏览器会自动帮我们设置。
前端页面展示图片
在文件上传时,我们将文件存储在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