nodejs 「图片上传」 原来🌶️么简单

255 阅读3分钟

1. 需求描述

当项目需要上传图片或文件时(比如上传头像),前端将会发送Content-Type:multipart/form-dataPost请求,将本地图片或文件上传到后端,后端将会生成对应的图片路径返回,拿到这个图片路径就能在浏览器显示或者下载这张图片啦。那具体是怎么实现的呢?下面以处理图片为例。

2. 步骤

安装mutiparty

mutiparty能够帮助我们处理mutipart/form-data的请求,拿到前端传来的文件和属性。

npm install multiparty --save

引入相关包

// 处理 mutipart/form-data
const fs = require('fs');
const multiparty = require('multiparty');
const path = require('path');
// 对时间进行格式化的函数
const Date = require('./format')

在目录下准备一个文件存储的文件夹

新建一个upload文件夹,前端上传的图片资源都会放在这个目录下的img文件夹中。

image.png

处理加载图片

定义一个upload的函数,对前端传入的图片进行处理,生成相应图片路径。

const upload = (req, res) => {
    let form = new multiparty.Form()
    // 设置文件存储路径
    form.uploadDir = path.join(__dirname, '.././upload/img') 
    // 解析前端传输的文件
    form.parse(req, (err, fields, files) => {
        if (err) {
            res.send({code:500, msg: '上传失败,' + err }))
        } else {
            const originalFilename = files.asset[0].originalFilename
            // 旧文件路径
            const oldPath = files.asset[0].path
            // 新文件路径:目录 + 当前时间 + 图片名
            const newPath = form.uploadDir + '/' + new Date().Format('yyyy-MM-dd-hh-mm-ss') + originalFilename
            // 修改存到静态资源文件夹下的图片路径,与返回用户的路径一致
            fs.renameSync(oldPath, newPath)
            const formUrl = new Date().Format('yyyy-MM-dd-hh-mm-ss') + originalFilename
            // 此处可以根据项目需求对数据库进行一些操作...
            }

            res.send(({code:200, msg: '上传成功', data: {formUrl}}))
        }
    })
}

module.exports = upload

为什么要用新文件路径去替代旧文件路径?

我们先来console.log(files),看看里面是长什么样子的。

image.png

如图,originalFilename是上传图片的图片名,path是默认本地的图片路径,即存储到upload/img文件夹下的图片路径。如果缺失了fs.renameSync(oldPath, newPath)这一步替换步骤,将会导致用户拿到的图片路径与后台中的图片路径不一致,如下图:
前端获取的路径:

image.png

后端存储的路径:

image.png 那在浏览器搜索引擎中输入该路径,自然是找不到目标对象啦。

为什么新图片路径的组成中要加入当前时间?

当前端多次上传同一张图片时,由于图片名相同,在静态资源目录下的图片路径也相同且唯一。但项目有时需要删除其中一张图片却不想影响到其他图片,所以要对同一张图片的多次上传以时间作为区分,产生不同的图片路径。

在index.js中将设置静态资源文件

//index.js或 app.js
app.use(express.static(path.join(__dirname, './upload')))

演示效果

本地上传图片: image.png 静态资源目录自动增加图片:

image.png 在浏览器中输入图片路径:

注意:静态资源路径中不需要输入/upload

image.png

这样就大功告成啦,是不是很简单呢?下载文件也是同理,感兴趣的朋友可以自己试一试。