Vue+NodeJs实现将图片上传至服务器

565 阅读3分钟

业务场景

修改用户信息——上传用户头像,当用户选择了图片后开始上传,返回该图片上传至服务器后的地址,显示在页面中,若点击取消修改按钮,则显示原来的头像,只有点击确定修改按钮时,才真正修改成功。

实现步骤

一、前端

前端上传图片用到了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'
}

到这为止,上传图片及获取图片资源的功能就完成了。