业务场景
修改用户信息——上传用户头像,当用户选择了图片后开始上传,返回该图片上传至服务器后的地址,显示在页面中,若点击取消修改按钮,则显示原来的头像,只有点击确定修改按钮时,才真正修改成功。
实现步骤
一、前端
前端上传图片用到了element-UI组件库中的upload组件,代码需要做如下配置:
<el-upload
v-if="isEdit"
:action="uploadURL"
:headers="headers"
:on-success="uploadImgSuccess"
>
<a href="#" class="upload">上传</a>
</el-upload>
- action:上传地址
- headers:请求头设置
- on-success:上传成功的回调函数
注:需要进行更多的配置可以到官网查看具体内容。
二、后端
1. 下载相关插件
到终端下载稍后要用到的相关插件:
// multiparty,用来传送图片
npm install multiparty
// uuid,用来生成唯一文件名
npm install uuid
// images,用来做24行的(图片处理)
npm install images
2. 编写上传图片的接口
// 使用express框架
const express = require('express')
const router = express.Router()
// 引入相关插件
const multiparty = require("multiparty")
const uuid = require('uuid');
const images = require("images")
// 编写接口
router.post('/upload', (req, res, next) => {
console.log('上传图片');
let form = new multiparty.Form()
form.parse(req, (err, field, files) => {
if(err) {
// 错误处理
}
// 获取旧文件名
const originFileName = files.file[0].originalFilename
// 上传的文件的格式
const format = originFileName.split(".")
// 设置上传的文件的新文件名,确保文件名唯一
const filename = uuid.v1() + "." + format[format.length - 1]
// 将文件存储到服务器本地,其中"public/images/"是服务器中图片的存储路径,需要确保服务器中有对应的文件夹,否则会报错
images(files.file[0].path) // load image from file
.save("public/images/" + filename, {
quality: 1000
})
// 给前端返回该图片地址,用于页面展示
const url = '/images/' + filename
res.send({
code: 200,
data: url
})
})
})
这里给前端返回图片地址是用于暂时性的展示,当点击确认修改按钮时,会再向服务器中发送一个请求,来修改数据库中存储的用户信息中的用户头像图片地址。
3. 编写获取图片资源的接口
页面中展示图片需要到服务器中获取图片资源,所以需要编写一个获取图片资源的接口:
const express = require('express')
const router = express.Router()
const fs = require('fs')
const path = require('path')
const url = require('url')
// 该文件是我编写的不同文件所对应的content-type,我把他放在了后面
const contentType = require('../utils/contentType.js')
// 因为上传图片时返回给前端的图片路径加了'/images',所以这里获取图片也需要对应添加'/images',若你使用了中间件进行分模块编写接口的话,就把'/images'放到外层匹配路径使用中间件那里即可。
router.get('/images/:url', (req, res, next) => {
const pathname = url.parse(req.url).pathname
// 获取静态资源文件夹
const imagesPath = path.resolve('public/images')
const realPath = path.join(imagesPath, pathname)
const format = contentType[pathname.split('.')[1]]
// 读取图片资源
fs.readFile(realPath, (err, data) => {
if(err) {
// 错误处理
}else {
res.writeHead(200, { 'content-type': `${format};charset=utf8` })
res.end(data)
}
})
})
contentType.js文件:
module.exports = {
html: 'text/html',
css: 'text/css',
gif: 'image/gif',
ico: 'image/x-icon',
jpg: 'image/jpeg',
png: 'image/png'
}
到这为止,上传图片及获取图片资源的功能就完成了。