Как использовать Formidable с API NextJS 13 для загрузки изображений и устранения ошибки запроса?
Я пытаюсь добавить в свое приложение функцию загрузки изображений. Я использую NextJS 13.4.4 и formidable@v3. Всякий раз, когда я загружаю изображение, я получаю эту ошибку:
ошибка TypeError: req.on не является функцией в IncomingForm.parse (webpack-internal:///(sc_server)/./node_modules/formidable/src/Formidable.js:182:13)
Примечание: этот код работает в версиях до next13.
У меня есть простая форма:
"use client";
import React, { useState } from "react";
import Image from "next/image";
import axios from "axios";
type Props = {};
export default function page({}: Props) {
const [uploading, setUoploading] = useState(false);
const [selectedImage, setSelectedImage] = useState("");
const [selectedFile, setSelectedFile] = useState<File>();
return (
<div className="max-w-4xl mx-auto p-20 space-y-6">
<label>
<input
type="file"
hidden
onChange={({ target }) => {
if (target.files) {
const file = target.files[0];
setSelectedImage(URL.createObjectURL(file));
setSelectedFile(file);
}
}}
/>
<div className="w-40 aspect-video rounded flex items-center justify-center border-2 border-dashed cursor-pointer">
{selectedImage ? (
<Image src={selectedImage} alt="" width={160} height={90} />
) : (
<span>Select Image</span>
)}
</div>
</label>
<button
onClick={handleUpload}
disabled={uploading}
style={{ opacity: uploading ? ".5" : "1" }}
className="bg-red-400 p-3 w-32 text-center rounded text-white"
>
{uploading ? "Uploading..." : "Upload"}
</button>
</div>
);
async function handleUpload() {
setUoploading(true);
try {
if (!selectedFile) {
return;
}
const formData = new FormData();
formData.append("myImage", selectedFile);
const data = await axios.post("/api/upload", formData);
console.log(data);
} catch (error: any) {
console.log(error);
}
setUoploading(false);
}
}
и внутренний код API:
import formidable from "formidable";
import { NextApiRequest } from "next";
import path from "path";
import fs from "node:fs/promises";
export const config = {
api: {
bodyParser: false,
},
};
async function readFile(
req: NextApiRequest,
saveLocally?: boolean
): Promise<{ fields: formidable.Fields; files: formidable.Files }> {
const options: formidable.Options = {};
if (saveLocally) {
options.uploadDir = path.join(process.cwd(), "/public/");
options.filename = (name, ext, path, form) => {
return `${Date.now().toString()}_${path.originalFilename}`;
};
}
const form = formidable(options);
return new Promise((resolve, reject) => {
form.parse(req, (err, fields, files) => {
if (err) reject(err);
resolve({ fields, files });
});
});
}
export async function POST(req: NextApiRequest) {
try {
await fs.readdir(path.join(process.cwd(), "/public"));
} catch (error) {
await fs.mkdir(path.join(process.cwd(), "/public"));
}
await readFile(req, true);
return new Response(JSON.stringify({ done: "ok" }));
}
Этот код я взял отсюда . Мне нужна помощь, чтобы выяснить, что изменить в следующей версии.