Возвращает undefined при выводе файла

Хочу обратиться к файлу на сервере и вывести его на клиенте, но req.file = undefined

upload.ts:

import { NextApiRequest, NextApiResponse } from 'next';
import nextConnect from 'next-connect';
import connectMongo from "../../utils/connectMongo";
import multer from 'multer';

connectMongo();

const upload = multer({
    storage: multer.diskStorage({
      destination: (req, file, cb) => cb(null, "../../public/uploads"),
      filename: (req, file, cb) => cb(null, file.originalname),
    })
});

const apiRoute = nextConnect({
    onNoMatch(req:NextApiRequest, res:NextApiResponse) {
        res.status(405).json({ error: `Method '${req.method}' Not Allowed` });
    }
});

apiRoute.post((req:any, res:NextApiResponse) => {
    try {
        upload.single("coverPhoto")(req, {}, err => {
            console.log(req.file); // undefined
        });
    } catch(e) {
        res.status(500).json({ success: false, message: "Ошибка сервера" })
    }
});

export default apiRoute;

export const config = {
    api: {
      bodyParser: true
    }
};

React handlers:

const [addProject, setAddProject] = React.useState<IProject>(projectDefaultState);

    const addCoverPhotoHandler = async(event) => {
        if (!event.target.files?.length) return;
        setAddProject({ ...addProject, coverPhoto: event.target.files[0] });
    }

    const addProjectHandler = async(event) => {
        event.preventDefault();

        const response = await fetch(`${process.env.API_URL}/api/upload`, {
            method: "POST",
            body: addProject.coverPhoto
        })
        const data = await response.json();
        console.log(data);
    }

Input:

<MyInput
  accept={[".png", ".svg", ".jpg", ".jpeg"]}
  multiple={false}
  name="coverPhoto"
  placeholder="Обложка"
  type="file"
  onChange={addCoverPhotoHandler}
/>
<MyButton onClick={addProjectHandler}>Опубликовать</MyButton>


Ответы (1 шт):

Автор решения: Алексей Яковлев

upload.ts:

import { NextApiResponse } from 'next';
import connectMongo from "../../../utils/connectMongo";
import multer from 'multer';
import path from "path";
import handler from '../handler';

connectMongo();

export const config = {
    api: {
        bodyParser: false
    }
}

const storage = multer.diskStorage({
    destination:(req, file, cb) => {
        cb(null, "public/uploads")
    },
    filename:(req, file, cb) => {
        cb(null, file.fieldname + "-" + Date.now() + path.extname(file.originalname))
    }
})

const uploadImages = multer({ storage });
const uploadCoverPhoto = uploadImages.single("coverPhoto");

handler.use(uploadCoverPhoto);

export default handler.post(async(req:any, res:NextApiResponse) => {
    try {
        const { file } = req;
        console.log(file);
    } catch(e) {
        console.log(e);
        res.status(500).json({
            success: false, message: "Ошибка сервера"
        })
    }
})

React handlers:

const addCoverPhotoHandler = async(event) => {
        if (!event.target.files?.length) return;
        const formData = new FormData();
        
        formData.append("coverPhoto", event.target.files[0]);

        const response:any = axios.post(`${process.env.API_URL}/api/upload`, formData, {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        })

        response.then((res:any) => {
            if (!res.data.success) {
                return setInfo({
                    type: "error",
                    text: "Ошибка при публикации обложки"
                })
            }
            setActive(false);
            imagesConfig.coverImage = res.data.infoFile;
        }).catch(err => {
            setInfo({
                type: "error",
                text: `Ошибка сервера: ${err.message}`
            })
        })
    }

→ Ссылка