客户端部分
注:我使用vite框架,element-plus以及axios,可以使用正常的html页面以及表单的文件上传功能替代。
页面部分
js
<template>
<el-upload
class="upload-demo"
drag
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
multiple="true"
:auto-upload="false"
list-type="picture-card"
:on-change="(file, fileLists) => change(file, fileLists)"
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">拖拽上传 or <em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip">图片大小限制为 500kb</div>
<button @click="上传照片">上传照片</button>
</template>
</el-upload>
<div v-for="(item,index) in 上传图片" v-key="index">
<img :src="item" alt="" />
</div>
</template>
使用el-upload选择上传文件,因为使用的是vite,在启动项目后,选择文件时返回的参数是临时挂载在服务器上的路径参数,与正常参数一样使用。
因为无法直接向服务器端传递图片,所以需要对图片进行转格式
js格式转换
注:一个FileReader对象只能在同一时间处理一张图片,所以需要创建多个对象处理多张图片
js
change(file, fileLists) {
console.log(file);
console.log(fileLists);
// let file = e.raw;
let 图片数组 = fileLists;
let 完成数组 = []
for (let i of 图片数组) {
let reader = new FileReader();
reader.onload = (e) => {
console.log(e.target.result); // 这是图片的 Base64 编码
完成数组.push(e.target.result)
this.未上传图片 = 完成数组
console.log(this.未上传图片)
this.$emit("imgs", this.未上传图片)
};
reader.readAsDataURL(i.raw);
}
},
由于处理期间是异步状态,所以必须先处理图片,等待格式转换完成,再上传服务器
上传
js
Axios.post(`/api/add`, {
img:this.上传照片,
}).then((ret) => {
console.log(ret.data)
})
服务器端
需要插件及服务器启动
js
const express = require("express")
const app = express()
const fs = require("fs/promises")
const cors = require("cors")
const path = require("path")
app.use(express.json({ limit: "50mb" }))
app.use("/", express.static(path.join(__dirname, "./资源")))
app.use(express.urlencoded({ extended: true, limit: "50mb" }))
app.use(cors())
app.listen(3080, () => {
console.log("服务器运行中")
console.log("http://localhost:3080")
})
cors
:跨域资源可以上传,处理express.json
:处理上传的数据,转为可读的格式express.urlencoded({ extended: true, limit: "50mb" })
:允许上传的数据大小app.use("/", express.static(path.join(__dirname, "./资源")))
:挂载资源,通过链接地址访问资源
数据处理
js
async function 上传图片(req) {
let 文件集 = []
let 数据库路径 = []
for (let i of req.body.img) {
let base64Data = i.replace(/^data:image\/\w+;base64,/, "")
let 图片 = new Buffer.from(base64Data, "base64")
let 文件夹 = "./资源/img/"
let 路径名 = "http://localhost:3080/img/"
let date = new Date()
let formattedDate =
date.getFullYear() +
"_" +
(date.getMonth() + 1).toString().padStart(2, "0") +
"_" +
date.getDate().toString().padStart(2, "0")
let randomNumber = Math.floor(Math.random() * 1000000)
.toString()
.padStart(6, "0")
let 文件名 = 文件夹 + formattedDate + "_" + randomNumber + ".jpg"
数据库路径.push(路径名 + formattedDate + "_" + randomNumber + ".jpg")
// 尝试创建文件夹,如果文件夹已存在,这个操作将不会有任何效果
await fs.mkdir(文件夹, { recursive: true })
// 写入文件
await fs.writeFile(文件名, 图片)
文件集.push(文件名)
}
console.log(数据库路径)
return 数据库路径
}
由于数据返回时带有base64
数据类型的前缀标识,所以需要先去掉,再用Buffer对象转格式使用fs模块存到本地。返回服务器资源路径,这样就可以访问已上传的图片了