NodeJs 从格式类型为二进制的 swagger 数组迭代 req.files

NodeJs Iterate over req.files from swagger array having format type as binary

我正在使用 swagger with Node and now stuck at multiple file upload part as i am able to get my files on server using swagger-fileupload-docs 文档页面。

middleware is multer 并且我在 server.ts 文件或 execution starts

的主文件中使用以下设置
import 'reflect-metadata';

import bodyParser from 'body-parser';
import cors from 'cors';
import express from 'express';
import bunyanMiddleware from 'express-bunyan-logger';
import fg from 'fast-glob';
import helmet from 'helmet';
import { createConnection } from 'typeorm';
import config from './config';
import ErrorHandler from './middlewares/errorHandler';
import logger from './utils/logger';

async function start(): Promise<void> {
    logger.info('Starting server...');

    await createConnection();

    const app = express();

    // Register middlewares
    const appUrl = new URL(config.app.url);
    app.use(cors({
        origin: config.env === 'production' ? appUrl.origin : '*',
    }));
    app.use(helmet());

    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({extended: true}));
    app.use(bunyanMiddleware({
        logger,
        parseUA: false,
        excludes: ['response-hrtime', 'req-headers', 'res-headers'],
        format: ':incoming :method :url :status-code',
    }));

    // Register routes
    const routes = await fg('./routes/*.(ts|js)', { cwd: __dirname });
    for (const routePath of routes) {
        const { default: router } = await import(routePath);
        if (typeof (router) === 'function') app.use(config.server.basePath, router);
    }

    // Error handler must come last...
    app.use(ErrorHandler);

    // Kick it off!
    app.listen(config.server.port, async () => {
        logger.info({ port: config.server.port }, 'Hey! I\'m listening...');
    });
}

start();


现在在 ROUTE 文件中 product.ts 的代码在下面使用 multer

import Joi from '@hapi/joi';
import express, { Router } from 'express';
import { ProductStatus, Role, } from '../models/enums';

import { authorize } from '../middlewares/authorize';
import { wrapAsync } from '../utils/asyncHandler';

import { Request, isUserReq } from './interfaces';
import { createBrand, deleteBrand, getAllBrands, updateBrand } from '../services/brand';
import multer from 'multer';
import { createProduct, deleteProduct, getAllProducts, updateProduct } from '../services/product';

const upload = multer({ dest: '/tmp/' })

const router = Router();

router.post('/products', authorize(), upload.array('imagesPath'), wrapAsync(async (req: Request, res: express.Response) => {
   
    var files = req.files;

    const { name, price, status, categoryId, vendorId } = await Joi
        .object({
            name: Joi.string().trim().min(3).max(50).required().label('Name'),
            price: Joi.number().min(1).max(10000).required().label('Price'),
            status: Joi.string().valid(ProductStatus.IN_STOCK, ProductStatus.OUT_OF_STOCK, ProductStatus.RUNNING_LOW).required().label('Status'),
            categoryId: Joi.string().trim().uuid().required().label('Category ID'),
            vendorId: Joi.string().trim().uuid().required().label('Vendor ID'),
            
        })
        .validateAsync(req.body);


但我无法遍历 req.files,因为它给出了以下错误

我的 swagger 文档如下。

/**
 * @swagger
 * /products:
 *   post:
 *     tags:
 *       - Product
 *     summary: Create a product
 *     consumes:
 *       - multipart/form-data
 *     security:
 *       - JWT: []
 *     requestBody:
 *       required: true
 *       content:
 *         multipart/form-data:
 *           schema:
 *             type: object
 *             properties:
 *               name:
 *                 description: Product name
 *                 type: string
 *               price:
 *                 description: Product price
 *                 type: string
 *               status:
 *                 description: Product status
 *                 type: string
 *                 enum: [OUT_OF_STOCK, IN_STOCK, RUNNING_LOW]
 *               imagesPath:
 *                 description: Product logo 
 *                 type: array
 *                 items:
 *                   type: string 
 *                   format: binary     
 *               categoryId:
 *                 type: string
 *               vendorId:
 *                 type: string
 *     produces:
 *       - multipart/form-data
 *     responses:
 *       200:
 *         description: OK
 *         content:
 *           application/json:
 *             schema:
 *               $ref: '#/components/schemas/Product'
 *             example:
 *               id: 2efa52e2-e9fd-4bd0-88bc-0132b2e837d9
 *               name: Product 1
 *               price: 25
 *               status: IN_STOCK   
 *               imagesPath: ['https://${config.s3.Images}.s3.amazonaws.com/${req.file.originalname}']
 *               categoryId: 2efa52e2-e9fd-4bd0-88bc-0132b2e837d9
 *               vendorId: 4efa52e5-e6fd-4bd0-68bc-0132b2e83ww49
 *       401:
 *         $ref: '#/components/responses/UnauthorizedError'
 *       409:
 *         $ref: '#/components/responses/ConflictError'
 *       500:
 *         $ref: '#/components/responses/InternalError'
 */


OPENAPI POST 我正在使用的 api 定义并使用二进制格式。

使用typeof req.files检查它的数组

如果它不是数组,那么您可以使用其中任何一个将其转换为数组,然后使用 forEach: Array(req.files).forEach(f => console.log(f))
Array.from(req.files).forEach(f => console.log(f))
[].forEach.call(req.files, console.log)