Multer не возвращает req.body и req.file с помощью следующего подключения
Я использую nextjs, и я хочу загрузить файл, поэтому я использовал next-connect, чтобы использовать multer
import nc from "next-connect";
import multer from "multer";
export const config = {
api: {
bodyParser: false,
},
}
const upload = multer({ dest: `${__dirname}../../public` });
const handler = nc()
.use(upload.single('image'))
.post(async (req, res)=>{
console.log(req.body); // undefined
console.log(req.file); // undefined
res.status(200).send("yo");
})
export default handler;
это код на стороне клиента:
function handleOnSubmit(e){
e.preventDefault();
const data = {};
var formData = new FormData(e.target);
for (const [name,value] of formData) {
data[name] = value;
}
data.type = data.type[0].toUpperCase();
data.name = data.name[0].toUpperCase();
axios({
method: "POST",
url:"/api/manager",
data,
config: {
headers: {
'content-type': 'multipart/form-data'
}
}
})
.then(res=>{
console.log(res);
})
.catch(err=>{
throw err
});
}
...
return(
...
<Form onSubmit={(e)=>handleOnSubmit(e)}>
...
</Form>
)
Я искал, и все, что я нашел, было связано с nodejs и expressjs, но ничего на next.js. Я понятия не имею, как действовать дальше.
4 ответа
для тех, кто все еще ищет решение, как использовать multer в качестве промежуточного программного обеспечения с nextJs, вот пример маршрута API, использование multer has middleware. Маршрут вызывает функцию getSignedUrl для загрузки файла в корзину.
работает nextJs v12 и multer 1.4.3
import multer from "multer";
import { NextApiRequest, NextApiResponse } from "next";
import { getSignedUrl } from "../../lib/uploadingToBucket";
function runMiddleware(
req: NextApiRequest & { [key: string]: any },
res: NextApiResponse,
fn: (...args: any[]) => void
): Promise<any> {
return new Promise((resolve, reject) => {
fn(req, res, (result: any) => {
if (result instanceof Error) {
return reject(result);
}
return resolve(result);
});
});
}
export const config = {
api: {
bodyParser: false,
},
};
const handler = async (
req: NextApiRequest & { [key: string]: any },
res: NextApiResponse
): Promise<void> => {
//const multerStorage = multer.memoryStorage();
const multerUpload = multer({ dest: "uploads/" });
await runMiddleware(req, res, multerUpload.single("file"));
const file = req.file;
const others = req.body;
const signedUrl = await getSignedUrl(others.bucketName, file.filename);
res.status(200).json({ getSignedUrl: signedUrl });
};
export default handler;
Когда я переключился на фреймворк Next.js, я сначала попытался загрузить файл с библиотекой «multer» и предпочел отказаться и использовать «грозный». Причина заключалась в том, что было доступно несколько ресурсов с Nextjs и multer.
И если я не ошибаюсь, multer следует добавить в качестве промежуточного программного обеспечения, так что это означает переписывание страницы server.js. Вы можете просмотреть эти темы:
- Создайте собственный сервер с Nextjs:https://nextjs.org/docs/advanced-features/custom-server
- И добавление промежуточного программного обеспечения: https://nextjs.org/docs/api-routes/api-middlewares#connectexpress-middleware-support
Если вы не хотите иметь с этим дело, вы можете проверить простую суть использования этой огромной библиотеки ресурсов: https://gist.github.com/agmm/da47a027f3d73870020a5102388dd820
И это созданный мной скрипт загрузки файлов: https://github.com/fatiiates/rest-w-nextjs/blob/main/src/assets/lib/user/file/upload.ts
была такая же проблема. не знаю, такой же ли он, как у вас, но на случай, если это может кому-то помочь ... когда я переключил multer на использование хранилища памяти, а не настольного хранилища, он работал нормально ... в моем случае я использовал другое промежуточное ПО после multer для загрузки в aws s3, поэтому мне не нужно было постоянно хранить файл в ./public .. Мне просто нужен был req.file, доступный в следующем промежуточном программном обеспечении. В вашем случае попробуйте изменить
const upload = multer({ dest: `${__dirname}../../public` });
к
const storage = multer.memoryStorage()
const upload = multer({storage: storage});
Оказалось, что все, что вам нужно, это отключить встроенный анализатор тела NextJS для конкретного маршрута API ( https://nextjs.org/docs/api-routes/api-middlewares#custom-config ):
// The following should be exported from your API route file
export const config = {
api: { bodyParser: false },
};