目录结构
my-koa-app/
├── config/ # 配置文件夹
│ └── database.js # 数据库连接配置
├── controllers/ # 控制器,包含具体的业务逻辑
│ └── uploadImageController.js # 用户相关的控制器
├── models/ # Mongoose 数据模型
│ └── uploadImage.js # 用户模型
├── routes/ # 路由定义
│ └── routes.js # 用户相关路由
├── uploads/ # 上传图片目录
├── app.js # Koa 应用的入口文件
└── package.json # 项目配置文件
安装npm包
npm install koa koa-router koa-bodyparser mongoose koa-static koa-multer
代码示例
app.js
const Koa = require('koa');
const bodyParser = require('koa-bodyparser');
const connectDB = require('./config/database');
const koaStatic = require('koa-static');
const userRoutes = require('./routes/routes');//引入路由
const path = require('path');
// 连接到数据库
connectDB();
const app = new Koa();
// 使用 bodyParser 解析请求体
app.use(bodyParser());
// 静态文件服务
app.use(koaStatic(path.join(__dirname, 'uploads'))); // 提供上传文件的静态资源服务
// 加载 user 路由
app.use(userRoutes.routes()); // 使用 userRoutes 路由
app.use(userRoutes.allowedMethods()); // 使用 allowedMethods
// 启动服务器
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
config/database.js
// config/database.js
const mongoose = require('mongoose');
const connectDB = async () => {
try {
await mongoose.connect('mongodb://localhost:端口号/数据库名称');//例如:mongodb://localhost:27017/xxxx
console.log('MongoDB connected');
} catch (err) {
console.error(err);
}
};
module.exports = connectDB;
models/uploadImage.js
const mongoose = require('mongoose');
// 创建图片存储的 Schema 和 Model
const ImgSchema = new mongoose.Schema({
filename: String,//文件名称
path: String,//文件目录
url: String, // 用来存储图片的URL
createdAt: { type: Date, default: Date.now },//创建时间
});
const photoImg = mongoose.model('photoImg', ImgSchema);
module.exports = photoImg;
controllers/uploadImageController.js
const multer = require('@koa/multer');
const path = require('path');
const photoImg = require('../models/uploadImage'); // 引用正确的模型
// 配置上传目录,确保 uploads 目录存在
const upload = multer({
dest: path.join(__dirname, '/../uploads/'), // 上传的文件存储路径
limits: { fileSize: 5 * 1024 * 1024 }, // 限制文件大小为 5MB
});
// 上传图片接口的逻辑
const uploadImage = async (ctx) => {
const { file } = ctx.request; // 获取上传的文件
console.log('File:', file); // 打印文件信息
if (!file) {
ctx.status = 400;
ctx.body = { error: 'No file uploaded' }; // 如果没有文件上传
return;
}
const imageUrl = `http://localhost:3000/uploads/${file.filename}`; // 图片的 URL 地址
// 保存文件信息到数据库
const newPhoto = new photoImg({
filename: file.originalname,
path: file.path,
url: imageUrl,
});
try {
await newPhoto.save();
ctx.status = 201;
ctx.body = { success: true, url: imageUrl }; // 返回图片的 URL
} catch (err) {
ctx.status = 500;
ctx.body = { error: 'Failed to save image', details: err.message };
}
};
// 获取所有图片信息
const getPhotos = async (ctx) => {
try {
const photos = await photoImg.find(); // 查询所有图片
ctx.body = { success: true, data: photos };
} catch (err) {
ctx.status = 500;
ctx.body = { error: 'Failed to fetch photos' };
}
};
// 获取指定 ID 的图片信息
const getPhotoById = async (ctx) => {
const { id } = ctx.params;
try {
const photo = await photoImg.findById(id); // 根据 ID 查找图片
if (!photo) {
ctx.status = 404;
ctx.body = { success: false, message: 'Photo not found' };
} else {
ctx.status = 200;
ctx.body = { success: true, data: photo };
}
} catch (err) {
ctx.status = 500;
ctx.body = { success: false, message: 'Network error' };
}
};
module.exports = {
uploadImage,
getPhotos,
getPhotoById,
upload, // 导出上传中间件
};
routes/routes.js
// routes/routes.js
const Router = require('koa-router');
const imgController = require('../controllers/uploadImageController')
const router = new Router();
// 图片上传接口
// 定义 Post 请求 - 获取用户信息
router.post('/upload', imgController.upload.single('image'), imgController.uploadImage);
// 定义 GET 请求 - 获取所有图片
router.get('/photos', imgController.getPhotos);
// 定义 GET 请求 - 获取指定 ID 的图片
router.get('/photos/:id', imgController.getPhotoById);
module.exports = router;
测试
发起postman请求,参数为image,格式类型为file
本地上传file打印结果:
请求前uploads目录为空
请求成功后uploads添加成功数据
查看数据库path,url目录保存图片,是否访问成功