上传图片

安装依赖

npm i uuid

用于生成唯一 id

server/api/upload/image.post.ts

import { readMultipartFormData, sendError } from "h3";
import { v4 as uuidv4 } from "uuid";
import fs from "fs";
import path from "path";export default defineEventHandler(async (event) => {const images = await readMultipartFormData(event);if (!images) {return sendError(event,createError({ statusCode: 400, statusMessage: "未找到图片文件" }));}// 验证文件类型和大小的函数const validateImage = (image: any) => {const allowedMimeTypes = ["image/jpeg","image/png","image/gif","image/webp",];if (!allowedMimeTypes.includes(image.type || "")) {return { valid: false, message: `不支持的文件类型: ${image.filename}` };}const maxSize = 5 * 1024 * 1024; // 5MBif (image.data.length > maxSize) {return {valid: false,message: `文件大小超过限制: ${image.filename} (最大 5MB)`,};}return { valid: true };};// 验证所有图片for (const image of images) {const validation = validateImage(image);if (!validation.valid) {return sendError(event,createError({statusCode: 400,statusMessage: validation.message,}));}}// 创建上传目录(如果不存在)const uploadDir = path.join(process.cwd(), "public", "uploads");if (!fs.existsSync(uploadDir)) {fs.mkdirSync(uploadDir, { recursive: true });}try {// 保存所有图片并收集结果const results = [];for (const image of images) {let ext = "png";let filename_pre = `${Date.now()}_${uuidv4()}`;if (image.filename) {let fileNameList = image.filename?.split(".") || [];if (fileNameList.length > 0) {filename_pre = fileNameList[0] + "_" + filename_pre;}ext = fileNameList.pop() || "png";}const filename = `${filename_pre}.${ext}`;const filePath = path.join(uploadDir, filename);fs.writeFileSync(filePath, image.data);results.push({url: `/uploads/${filename}`,filename,size: image.data.length,originalName: image.filename,});}// 返回所有文件信息return {success: true,count: results.length,data: results,};} catch (error) {return sendError(event,createError({ statusCode: 500, statusMessage: "文件保存失败" }));}
});

接口调用

try {const formData = new FormData();formData.append("image", file);const response = await $fetch("/api/upload/image", {method: "POST",body: formData,headers: {Accept: "application/json",},});return response;} catch (err: any) {error.value = err.message || "上传失败,请重试";throw err;}

图片存储位置

public/uploads

删除已上传的图片

server/api/upload/delete.post.ts

import { sendError } from "h3";
import fs from "fs";
import path from "path";export default defineEventHandler(async (event) => {// 获取请求体数据const body = await readBody(event);// 验证请求数据if (!body || !body.filename) {return sendError(event,createError({statusCode: 400,statusMessage: "缺少文件名",}));}// 构建文件路径const uploadDir = path.join(process.cwd(), "public", "uploads");const filePath = path.join(uploadDir, body.filename);try {// 检查文件是否存在if (!fs.existsSync(filePath)) {return sendError(event,createError({statusCode: 404,statusMessage: "图片文件不存在",}));}// 删除文件fs.unlinkSync(filePath);return {success: true,message: "图片删除成功",filename: body.filename,};} catch (error) {return sendError(event,createError({statusCode: 500,statusMessage: "删除文件失败",}));}
});

接口调用

传入已上传图片的文件名

$fetch(`/api/upload/delete`, {body: { filename: imageName.value },method: "POST",}).then((res) => {callbackMessage.value = {show: true,valid: true,content: `删除成功`,};imageUrl.value = "";});