如何解决Swagger UI上传文件至Node.js时参数undefined问题
问题
Swagger UI 文件上传功能异常,选择文件执行上传后,req.body、req.files等参数均返回undefined,需要实现从Swagger将文件上传至Node.js应用的指定文件夹中,当前代码如下:
const express = require('express'); const multer = require('multer'); const swaggerJSDoc = require('swagger-jsdoc'); const swaggerUI = require('swagger-ui-express'); const path = require('path'); const app = express(); const port = process.env.PORT || 3000; // Multer middleware setup for file uploads const storage = multer.memoryStorage(); const uploads = multer({ dest: __dirname + "/uploads" }); // Define the Swagger options const swaggerOptions = { definition: { openapi: '3.0.0', info: { title: 'File Upload API', version: '1.0.0', }, }, apis: ['./app.js'], // Point to the current file for Swagger annotations }; // Initialize Swagger-jsdoc const swaggerSpec = swaggerJSDoc(swaggerOptions); // Serve Swagger UI app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(swaggerSpec)); // Serve static files (e.g., HTML forms) app.use(express.static(path.join(__dirname, 'public'))); /** * @swagger * /upload: * post: * summary: Upload a file. * consumes: * - multipart/form-data * parameters: * - in: formData * name: file * schema: * type: file * type: file * required: true * responses: * 200: * description: File uploaded successfully. */ app.post('/upload', uploads.single('file'), (req, res) => { console.log(req.body) console.log(req.files) console.log(req.file) const uploadedFile = req.file if (!uploadedFile) { return res.status(400).json({ message: 'No file uploaded.' }); } // Handle the uploaded file, e.g., save it or process it. // For this example, we are just sending back a success message. res.json({ message: 'File uploaded successfully' }); }); app.listen(port, () => { console.log(`Server is running on port ${port}`); });
解决方案
问题核心是Swagger OpenAPI 3.0语法不符合规范,导致请求格式不匹配,Multer无法正确解析文件,以下是修复方案:
1. 修正Swagger注释(适配OpenAPI 3.0)
OpenAPI 3.0已废弃consumes和formData参数,需改用requestBody定义multipart/form-data类型请求,确保Swagger UI发送的请求格式符合Multer解析要求。
2. 优化Multer路径配置
使用path.join拼接存储路径,避免因系统路径分隔符差异导致的错误。
修复后的完整代码
const express = require('express'); const multer = require('multer'); const swaggerJSDoc = require('swagger-jsdoc'); const swaggerUI = require('swagger-ui-express'); const path = require('path'); const app = express(); const port = process.env.PORT || 3000; // Multer配置:指定文件存储路径,用path.join适配不同系统 const uploads = multer({ dest: path.join(__dirname, 'uploads') }); // Swagger配置 const swaggerOptions = { definition: { openapi: '3.0.0', info: { title: '文件上传API', version: '1.0.0', }, }, apis: ['./app.js'], }; const swaggerSpec = swaggerJSDoc(swaggerOptions); app.use('/api-docs', swaggerUI.serve, swaggerUI.setup(swaggerSpec)); app.use(express.static(path.join(__dirname, 'public'))); /** * @swagger * /upload: * post: * summary: 上传文件 * requestBody: * required: true * content: * multipart/form-data: * schema: * type: object * properties: * file: * type: string * format: binary * responses: * 200: * description: 文件上传成功 * 400: * description: 未选择文件 */ app.post('/upload', uploads.single('file'), (req, res) => { console.log('请求体:', req.body); console.log('上传的文件:', req.file); if (!req.file) { return res.status(400).json({ message: '未选择文件' }); } res.json({ message: '文件上传成功', fileInfo: { 存储文件名: req.file.filename, 原始文件名: req.file.originalname, 文件大小: req.file.size } }); }); app.listen(port, () => { console.log(`服务器运行在端口 ${port}`); });
额外注意事项
- 确保项目根目录下的
uploads文件夹存在,Multer会自动创建该文件夹,但权限不足时可能报错,建议手动创建并设置合适权限。 - 不要在express中添加
express.json()或express.urlencoded()中间件处理multipart/form-data请求,Multer会自行解析这类请求,添加后可能导致解析冲突。
内容的提问来源于stack exchange,提问作者NEUTRON
相关产品推荐
相关产品推荐

